diff --git a/.gitignore b/.gitignore
index 16aaf68b70b..74de941b768 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,4 +10,9 @@ result-*
/doc/manual.pdf
.version-suffix
-.DS_Store
\ No newline at end of file
+.DS_Store
+
+/pkgs/applications/kde-apps-*/tmp/
+/pkgs/development/libraries/kde-frameworks-*/tmp/
+/pkgs/development/libraries/qt-5/*/tmp/
+/pkgs/desktops/plasma-*/tmp/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000000..dbb04e29ee0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: python
+python: "3.4"
+sudo: required
+before_install: ./maintainers/scripts/travis-nox-review-pr.sh nix
+install: ./maintainers/scripts/travis-nox-review-pr.sh nox
+script: ./maintainers/scripts/travis-nox-review-pr.sh build
diff --git a/.version b/.version
index d3a61dbd830..7bc03e791d4 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-14.10
\ No newline at end of file
+15.05
\ No newline at end of file
diff --git a/README.md b/README.md
index e59b15425e9..86a5568727e 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,26 @@
-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.
+[
+](https://nixos.org/nixos)
+
+[![Build Status](https://travis-ci.org/NixOS/nixpkgs.svg?branch=master)](https://travis-ci.org/NixOS/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/pr)](http://www.issuestats.com/github/nixos/nixpkgs) [![Issue Stats](http://www.issuestats.com/github/nixos/nixpkgs/badge/issue)](http://www.issuestats.com/github/nixos/nixpkgs)
+
+Nixpkgs is a collection of packages for [Nix](https://nixos.org/nix/) package
+manager.
+
+[NixOS](https://nixos.org/nixos/) linux distribution source code is located inside `nixos/` folder.
+
+* [NixOS installation instructions](https://nixos.org/nixos/manual/#ch-installation)
+* [Documentation (Nix Expression Language chapter)](https://nixos.org/nix/manual/#ch-expression-language)
+* [Manual (How to write packages for Nix)](https://nixos.org/nixpkgs/manual/)
+* [Manual (NixOS)](https://nixos.org/nixos/manual/)
+* [Continuous package builds for unstable/master](https://hydra.nixos.org/jobset/nixos/trunk-combined)
+* [Continuous package builds for 14.12 release](https://hydra.nixos.org/jobset/nixos/release-14.12)
+* [Tests for unstable/master](https://hydra.nixos.org/job/nixos/trunk-combined/tested#tabs-constituents)
+* [Tests for 14.12 release](https://hydra.nixos.org/job/nixos/release-14.12/tested#tabs-constituents)
+
+Communication:
-* [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)
+
+---
+[![Throughput Graph](https://graphs.waffle.io/nixos/nixpkgs/throughput.svg)](https://waffle.io/nixos/nixpkgs/metrics)
diff --git a/default.nix b/default.nix
index c1b9bfd39f9..bdbe13b3ea2 100644
--- a/default.nix
+++ b/default.nix
@@ -1,6 +1,6 @@
-if ! builtins ? nixVersion || builtins.compareVersions "1.6" builtins.nixVersion == 1 then
+if ! builtins ? nixVersion || builtins.compareVersions "1.8" builtins.nixVersion == 1 then
- abort "This version of Nixpkgs requires Nix >= 1.6, please upgrade!"
+ abort "This version of Nixpkgs requires Nix >= 1.8, please upgrade! See https://nixos.org/wiki/How_to_update_when_nix_is_too_old_to_evaluate_nixpkgs"
else
diff --git a/doc/contributing.xml b/doc/contributing.xml
index bcea404baee..f622845bf1a 100644
--- a/doc/contributing.xml
+++ b/doc/contributing.xml
@@ -10,9 +10,7 @@
$ git clone git://github.com/NixOS/nixpkgs.git
- $ cd nixpkgs/pkgs/top-level
-
- $ nix-build -A tarball release.nix
+ $ nix-build -A manual nixpkgs/pkgs/top-level/release.nix
Inside the built derivation you shall see manual/index.html file.
diff --git a/doc/language-support.xml b/doc/language-support.xml
index f5e89df57fc..f2b64c93d22 100644
--- a/doc/language-support.xml
+++ b/doc/language-support.xml
@@ -108,7 +108,7 @@ a preConfigure hook to generate a configuration
file used by Makefile.PL :
-{buildPerlPackage, fetchurl, db}:
+{ buildPerlPackage, fetchurl, db }:
buildPerlPackage rec {
name = "BerkeleyDB-0.36";
@@ -191,45 +191,548 @@ you need it.
-Python
+Python
- Python packages that
- use setuptools ,
- which many Python packages do nowadays, can be built very simply using
- the buildPythonPackage function. This function is
- implemented
- in pkgs/development/python-modules/generic/default.nix
- and works similarly to buildPerlPackage . (See
- for details.)
+ Currently supported interpreters are python26 , python27 ,
+ python32 , python33 , python34
+ and pypy .
- Python packages that use buildPythonPackage are
- defined
- in pkgs/top-level/python-packages.nix .
- Most of them are simple. For example:
+ python is an alias of python27 and python3 is an alias of python34 .
+
-
+
+ python26 and python27 do not include modules that require
+ external dependencies (to reduce dependency bloat). Following modules need to be added as
+ buildInput explicitly:
+
+
+
+ python.modules.bsddb
+ python.modules.curses
+ python.modules.curses_panel
+ python.modules.crypt
+ python.modules.gdbm
+ python.modules.sqlite3
+ python.modules.tkinter
+ python.modules.readline
+
+
+For convenience python27Full and python26Full
+are provided with all modules included.
+
+
+ Python packages that
+ use setuptools or distutils ,
+ can be built using the buildPythonPackage function as documented below.
+
+
+
+ All packages depending on any Python interpreter get appended $out/${python.libPrefix}/site-packages
+ to $PYTHONPATH if such directory exists.
+
+
+
+
+ Useful attributes on interpreters packages:
+
+
+
+ libPrefix
+
+ Name of the folder in ${python}/lib/ for corresponding interpreter.
+
+
+
+
+ interpreter
+
+ Alias for ${python}/bin/${executable}.
+
+
+
+
+ buildEnv
+
+ Function to build python interpreter environments with extra packages bundled together.
+ See for usage and documentation.
+
+
+
+
+ sitePackages
+
+ Alias for lib/${libPrefix}/site-packages .
+
+
+
+
+ executable
+
+ Name of the interpreter executable, ie python3.4 .
+
+
+
+
+buildPythonPackage function
+
+
+ The function is implemented in
+ pkgs/development/python-modules/generic/default.nix .
+ Example usage:
+
+
twisted = buildPythonPackage {
name = "twisted-8.1.0";
- src = fetchurl {
+ src = pkgs.fetchurl {
url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
};
- propagatedBuildInputs = [ pkgs.ZopeInterface ];
+ propagatedBuildInputs = [ self.ZopeInterface ];
meta = {
homepage = http://twistedmatrix.com/;
description = "Twisted, an event-driven networking engine written in Python";
- license = "MIT";
+ license = stdenv.lib.licenses.mit;
};
};
-
+
+
+ Most of Python packages that use buildPythonPackage are defined
+ in pkgs/top-level/python-packages.nix
+ and generated for each python interpreter separately into attribute sets python26Packages ,
+ python27Packages , python32Packages , python33Packages ,
+ python34Packages and pypyPackages .
+
+
+
+ buildPythonPackage mainly does four things:
+
+
+
+ In the configurePhase , it patches
+ setup.py to always include setuptools before
+ distutils for monkeypatching machinery to take place.
+
+
+
+ In the buildPhase , it calls
+ ${python.interpreter} setup.py build ...
+
+
+
+ In the installPhase , it calls
+ ${python.interpreter} setup.py install ...
+
+
+
+ In the postFixup phase, wrapPythonPrograms
+ bash function is called to wrap all programs in $out/bin/*
+ directory to include $PYTHONPATH and $PATH
+ environment variables.
+
+
+
+
+ By default doCheck = true is set and tests are run with
+ ${python.interpreter} setup.py test command in checkPhase .
+
+ propagatedBuildInputs packages are propagated to user environment.
+
+
+ By default meta.platforms is set to the same value
+ as the interpreter unless overriden otherwise.
+
+
+
+
+ buildPythonPackage parameters
+ (all parameters from mkDerivation function are still supported)
+
+
+
+ namePrefix
+
+ Prepended text to ${name} parameter.
+ Defaults to "python3.3-" for Python 3.3, etc. Set it to
+ ""
+ if you're packaging an application or a command line tool.
+
+
+
+
+ disabled
+
+ If true , package is not build for
+ particular python interpreter version. Grep around
+ pkgs/top-level/python-packages.nix
+ for examples.
+
+
+
+
+ setupPyInstallFlags
+
+ List of flags passed to setup.py install command.
+
+
+
+
+ setupPyBuildFlags
+
+ List of flags passed to setup.py build command.
+
+
+
+
+ pythonPath
+
+ List of packages to be added into $PYTHONPATH .
+ Packages in pythonPath are not propagated into user environment
+ (contrary to propagatedBuildInputs ).
+
+
+
+
+ preShellHook
+
+ Hook to execute commands before shellHook .
+
+
+
+
+ postShellHook
+
+ Hook to execute commands after shellHook .
+
+
+
+
+ distutilsExtraCfg
+
+ Extra lines passed to [easy_install] section of
+ distutils.cfg (acts as global setup.cfg
+ configuration).
+
+
+
+
+
+
+
+python.buildEnv function
+
+ Create Python environments using low-level pkgs.buildEnv function. Example default.nix :
+
+
+ {};
+
+python.buildEnv.override {
+ extraLibs = [ pkgs.pythonPackages.pyramid ];
+ ignoreCollisions = true;
+}]]>
+
+
+ Running nix-build will create
+ /nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
+ with wrapped binaries in bin/ .
+
+
+
+
+ python.buildEnv arguments
+
+
+
+ extraLibs
+
+ List of packages installed inside the environment.
+
+
+
+
+ postBuild
+
+ Shell command executed after the build of environment.
+
+
+
+
+ ignoreCollisions
+
+ Ignore file collisions inside the environment (default is false ).
+
+
+
+
+
+Tools
+
+Packages inside nixpkgs are written by hand. However many tools
+exist in community to help save time. No tool is preferred at the moment.
+
+
+
+ python2nix
+ by Vladimir Kirillov
+
+
+
+ pypi2nix
+ by Rok Garbas
+
+
+
+ pypi2nix
+ by Jaka Hudoklin
+
+
+
+
+
+
+Development
+
+
+ To develop Python packages buildPythonPackage has
+ additional logic inside shellPhase to run
+ ${python.interpreter} setup.py develop for the package.
+
+
+ shellPhase is executed only if setup.py
+ exists.
+
+
+ Given a default.nix :
+
+
+ {};
+
+buildPythonPackage {
+ name = "myproject";
+
+ buildInputs = with pkgs.pythonPackages; [ pyramid ];
+
+ src = ./.;
+}]]>
+
+
+ Running nix-shell with no arguments should give you
+ the environment in which the package would be build with
+ nix-build .
+
+
+
+ Shortcut to setup environments with C headers/libraries and python packages:
+
+ $ nix-shell -p pythonPackages.pyramid zlib libjpeg git
+
+
+
+ There is a boolean value lib.inNixShell set to
+ true if nix-shell is invoked.
+
+
+
+
+FAQ
+
+
+
+
+ How to solve circular dependencies?
+
+ If you have packages A and B that
+ depend on each other, when packaging B override package
+ A not to depend on B as input
+ (and also the other way around).
+
+
+
+
+ install_data / data_files problems resulting into error: could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc': Permission denied
+
+
+ Known bug in setuptools install_data does not respect --prefix. Example of
+ such package using the feature is pkgs/tools/X11/xpra/default.nix . As workaround
+ install it as an extra preInstall step:
+
+ ${python.interpreter} setup.py install_data --install-dir=$out --root=$out
+sed -i '/ = data_files/d' setup.py
+
+
+
+
+ Rationale of non-existent global site-packages
+
+ There is no need to have global site-packages in Nix. Each package has isolated
+ dependency tree and installing any python package will only populate $PATH
+ inside user environment. See to create self-contained
+ interpreter with a set of packages.
+
+
+
+
+
+
+
+
+Contributing guidelines
+
+ Following rules are desired to be respected:
+
+
+
+
+
+ Make sure package builds for all python interpreters. Use disabled argument to
+ buildPythonPackage to set unsupported interpreters.
+
+
+
+ If tests need to be disabled for a package, make sure you leave a comment about reasoning.
+
+
+
+ Packages in pkgs/top-level/python-packages.nix
+ are sorted quasi-alphabetically to avoid merge conflicts.
+
+
+
+
+
+
+
+
+
+Ruby
+ There currently is support to bundle applications that are packaged as Ruby gems. The utility "bundix" allows you to write a Gemfile , let bundler create a Gemfile.lock , and then convert
+ this into a nix expression that contains all Gem dependencies automatically.
+
+ For example, to package sensu, we did:
+
+
+ Gemfile
+source 'https://rubygems.org'
+gem 'sensu'
+$ bundler package --path /tmp/vendor/bundle
+$ $(nix-build '&nixpkgs>' -A bundix)/bin/bundix
+$ cat > default.nix
+{ lib, bundlerEnv, ruby }:
+
+bundlerEnv {
+ name = "sensu-0.17.1";
+
+ inherit ruby;
+ gemfile = ./Gemfile;
+ lockfile = ./Gemfile.lock;
+ gemset = ./gemset.nix;
+
+ meta = with lib; {
+ description = "A monitoring framework that aims to be simple, malleable,
+and scalable.";
+ homepage = http://sensuapp.org/;
+ license = with licenses; mit;
+ maintainers = with maintainers; [ theuni ];
+ platforms = platforms.unix;
+ };
+}]]>
+
+
+Please check in the Gemfile , Gemfile.lock and the gemset.nix so future updates can be run easily.
+
+
+
+
+Go
+
+The function buildGoPackage builds
+standard Go packages.
+
+
+buildGoPackage
+
+net = buildGoPackage rec {
+ name = "go.net-${rev}";
+ goPackagePath = "code.google.com/p/go.net";
+ subPackages = [ "ipv4" "ipv6" ];
+ rev = "28ff664507e4";
+ src = fetchhg {
+ inherit rev;
+ url = "https://${goPackagePath}";
+ sha256 = "1lkz4c9pyz3yz2yz18hiycvlfhgy3jxp68bs7mv7bcfpaj729qav";
+ };
+ propagatedBuildInputs = [ goPackages.text ];
+};
+
+
+
+ is an example expression using buildGoPackage,
+the following arguments are of special significance to the function:
+
+
+
+
+
+ goPackagePath specifies the package's canonical Go import path.
+
+
+
+
+
+ subPackages limits the builder from building child packages that
+ have not been listed. If subPackages is not specified, all child
+ packages will be built.
+
+
+ In this example only code.google.com/p/go.net/ipv4 and
+ code.google.com/p/go.net/ipv4 will be built.
+
+
+
+
+
+ propagatedBuildInputs is where the dependencies of a Go library are
+ listed. Only libraries should list propagatedBuildInputs . If a standalone
+ program is being build instead, use buildInputs . If a library's tests require
+ additional dependencies that are not propagated, they should be listed in buildInputs .
+
+
+
+
+
+
+
+
+Reusable Go libraries may be found in the goPackages set. You can test
+build a Go package as follows:
+
+
+$ nix-build -A goPackages.net
+
+
+
+
+
+You may use Go packages installed into the active Nix profiles by adding
+the following to your ~/.bashrc:
+
+
+for p in $NIX_PROFILES; do
+ GOPATH="$p/share/go:$GOPATH"
+done
+
+
+
+ To extract dependency information from a Go package in automated way use go2nix.
@@ -314,6 +817,90 @@ Runtime) instead of the OpenJRE.
+Lua
+
+
+ Lua packages are built by the buildLuaPackage function. This function is
+ implemented
+ in
+ pkgs/development/lua-modules/generic/default.nix
+ and works similarly to buildPerlPackage . (See
+ for details.)
+
+
+
+ Lua packages are defined
+ in pkgs/top-level/lua-packages.nix .
+ Most of them are simple. For example:
+
+
+fileSystem = buildLuaPackage {
+ name = "filesystem-1.6.2";
+ src = fetchurl {
+ url = "https://github.com/keplerproject/luafilesystem/archive/v1_6_2.tar.gz";
+ sha256 = "1n8qdwa20ypbrny99vhkmx8q04zd2jjycdb5196xdhgvqzk10abz";
+ };
+ meta = {
+ homepage = "https://github.com/keplerproject/luafilesystem";
+ hydraPlatforms = stdenv.lib.platforms.linux;
+ maintainers = with maintainers; [ flosse ];
+ };
+};
+
+
+
+
+ Though, more complicated package should be placed in a seperate file in
+ pkgs/development/lua-modules .
+
+
+ Lua packages accept additional parameter disabled , which defines
+ the condition of disabling package from luaPackages. For example, if package has
+ disabled assigned to lua.luaversion != "5.1" ,
+ it will not be included in any luaPackages except lua51Packages, making it
+ only be built for lua 5.1.
+
+
+
+
+Coq
+
+ Coq libraries should be installed in
+ $(out)/lib/coq/${coq.coq-version}/user-contrib/ .
+ Such directories are automatically added to the
+ $COQPATH environment variable by the hook defined
+ in the Coq derivation.
+
+
+ Some libraries require OCaml and sometimes also Camlp5. The exact
+ versions that were used to build Coq are saved in the
+ coq.ocaml and coq.camlp5
+ attributes.
+
+
+ Here is a simple package example. It is a pure Coq library, thus it
+ only depends on Coq. Its makefile has been
+ generated using coq_makefile so we only have to
+ set the $COQLIB variable at install time.
+
+
+{stdenv, fetchurl, coq}:
+stdenv.mkDerivation {
+ src = fetchurl {
+ url = http://coq.inria.fr/pylons/contribs/files/Karatsuba/v8.4/Karatsuba.tar.gz;
+ sha256 = "0ymfpv4v49k4fm63nq6gcl1hbnnxrvjjp7yzc4973n49b853c5b1";
+ };
+
+ name = "coq-karatsuba";
+
+ buildInputs = [ coq ];
+
+ installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
+}
+
+
+
-
\ No newline at end of file
+
diff --git a/nixos/doc/manual/installation/installing.xml b/nixos/doc/manual/installation/installing.xml
index b140c56fbee..c21759bc926 100644
--- a/nixos/doc/manual/installation/installing.xml
+++ b/nixos/doc/manual/installation/installing.xml
@@ -11,14 +11,9 @@
Boot from the CD.
The CD contains a basic NixOS installation. (It
- also contains Memtest86+, useful if you want to test new hardware.)
+ also contains Memtest86+, useful if you want to test new hardware).
When it’s finished booting, it should have detected most of your
- hardware and brought up networking (check
- ifconfig ). Networking is necessary for the
- installer, since it will download lots of stuff (such as source
- tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
- server on your network. Otherwise configure networking manually
- using ifconfig .
+ hardware.
The NixOS manual is available on virtual console 8
(press Alt+F8 to access).
@@ -29,6 +24,16 @@
If you downloaded the graphical ISO image, you can
run start display-manager to start KDE.
+ The boot process should have brought up networking (check
+ ip a ). Networking is necessary for the
+ installer, since it will download lots of stuff (such as source
+ tarballs or Nixpkgs channel binaries). It’s best if you have a DHCP
+ server on your network. Otherwise configure networking manually
+ using ifconfig .
+ To manually configure the network on the graphical installer,
+ first disable network-manager with
+ systemctl stop network-manager .
+
The NixOS installer doesn’t do any partitioning or
formatting yet, so you need to that yourself. Use the following
commands:
diff --git a/nixos/doc/manual/installation/obtaining.xml b/nixos/doc/manual/installation/obtaining.xml
index ceeeb5c0ac0..afd6c9543f7 100644
--- a/nixos/doc/manual/installation/obtaining.xml
+++ b/nixos/doc/manual/installation/obtaining.xml
@@ -8,9 +8,14 @@
NixOS ISO images can be downloaded from the NixOS
-homepage. These can be burned onto a CD. It is also possible
-to copy them onto a USB stick and install NixOS from there. For
-details, see the . There are a number of installation options. If
+you happen to have an optical drive and a spare CD, burning the
+image to CD and booting from that is probably the easiest option.
+Most people will need to prepare a USB stick to boot from.
+Unetbootin is recommended and the process is described in brief below.
+Note that systems which use UEFI require some additional manual steps.
+If you run into difficulty a number of alternative methods are presented
+in the NixOS
Wiki.
@@ -22,7 +27,7 @@ running NixOS system through several other means:
Using virtual appliances in Open Virtualization Format (OVF)
that can be imported into VirtualBox. These are available from
the NixOS
- homepage.
+ download page.
Using AMIs for Amazon’s EC2. To find one for your region
diff --git a/nixos/doc/manual/installation/upgrading.xml b/nixos/doc/manual/installation/upgrading.xml
index ed71a7e23a3..5a9d1f24f7c 100644
--- a/nixos/doc/manual/installation/upgrading.xml
+++ b/nixos/doc/manual/installation/upgrading.xml
@@ -14,8 +14,8 @@ been built. These channels are:
- Stable channels, such as nixos-14.04 .
+ Stable channels , such as nixos-14.12 .
These only get conservative bug fixes and package upgrades. For
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
@@ -23,26 +23,40 @@ been built. These channels are:
3.11.x (a major change that has the
potential to break things). Stable channels are generally
maintained until the next stable branch is created.
+
- The unstable channel, nixos-unstable .
+ The unstable channel , nixos-unstable .
This corresponds to NixOS’s main development branch, and may thus
see radical changes between channel updates. It’s not recommended
for production systems.
+
+ Small channels , such as nixos-14.12-small
+ or nixos-unstable-small . These
+ are identical to the stable and unstable channels described above,
+ except that they contain fewer binary packages. This means they
+ get updated faster than the regular channels (for instance, when a
+ critical security patch is committed to NixOS’s source tree), but
+ may require more packages to be built from source than
+ usual. They’re mostly intended for server environments and as such
+ contain few GUI applications.
+
To see what channels are available, go to . (Note that the URIs of the
+xlink:href="https://nixos.org/channels"/>. (Note that the URIs of the
various channels redirect to a directory that contains the channel’s
latest version and includes ISO images and VirtualBox
appliances.)
When you first install NixOS, you’re automatically subscribed to
the NixOS channel that corresponds to your installation source. For
-instance, if you installed from a 14.04 ISO, you will be subscribed to
-the nixos-14.04 channel. To see which NixOS
+instance, if you installed from a 14.12 ISO, you will be subscribed to
+the nixos-14.12 channel. To see which NixOS
channel you’re subscribed to, run the following as root:
@@ -53,20 +67,26 @@ nixos https://nixos.org/channels/nixos-unstable
To switch to a different NixOS channel, do
-$ nix-channel --add http://nixos.org/channels/channel-name nixos
+$ nix-channel --add https://nixos.org/channels/channel-name nixos
(Be sure to include the nixos parameter at the
-end.) For instance, to use the NixOS 14.04 stable channel:
+end.) For instance, to use the NixOS 14.12 stable channel:
-$ nix-channel --add http://nixos.org/channels/nixos-14.04 nixos
+$ nix-channel --add https://nixos.org/channels/nixos-14.12 nixos
-But it you want to live on the bleeding edge:
+If you have a server, you may want to use the “small” channel instead:
-$ nix-channel --add http://nixos.org/channels/nixos-unstable nixos
+$ nix-channel --add https://nixos.org/channels/nixos-14.12-small nixos
+
+
+And if you want to live on the bleeding edge:
+
+
+$ nix-channel --add https://nixos.org/channels/nixos-unstable nixos
diff --git a/nixos/doc/manual/man-nixos-install.xml b/nixos/doc/manual/man-nixos-install.xml
index 0ebee7d23f9..7ad1be1ec10 100644
--- a/nixos/doc/manual/man-nixos-install.xml
+++ b/nixos/doc/manual/man-nixos-install.xml
@@ -11,12 +11,45 @@
nixos-install
- install NixOS
+ install bootloader and NixOS
nixos-install
+
+ -I
+ path
+
+
+ --root
+ root
+
+
+
+ --max-jobs
+ -j
+
+ number
+
+
+ --cores
+ number
+
+
+ --option
+ name
+ value
+
+
+ --show-trace
+
+
+ --chroot
+
+
+ --help
+
@@ -55,6 +88,87 @@ it.
+Options
+
+This command accepts the following options:
+
+
+
+
+ --root
+
+ Defaults to /mnt . If this option is given, treat the directory
+ root as the root of the NixOS installation.
+
+
+
+
+
+ -I
+
+ Add a path to the Nix expression search path. This option may be given multiple times.
+ See the NIX_PATH environment variable for information on the semantics of the Nix search path.
+ Paths added through -I take precedence over NIX_PATH.
+
+
+
+ --max-jobs
+ -j
+
+ Sets the maximum number of build jobs that Nix will
+ perform in parallel to the specified number. The default is 1 .
+ A higher value is useful on SMP systems or to exploit I/O latency.
+
+
+
+
+ --cores
+
+ Sets the value of the NIX_BUILD_CORES
+ environment variable in the invocation of builders. Builders can
+ use this variable at their discretion to control the maximum amount
+ of parallelism. For instance, in Nixpkgs, if the derivation
+ attribute enableParallelBuilding is set to
+ true , the builder passes the
+ -jN flag to GNU Make.
+ The value 0 means that the builder should use all
+ available CPU cores in the system.
+
+
+
+ --option name value
+
+ Set the Nix configuration option
+ name to value .
+
+
+
+
+ --show-trace
+
+ Causes Nix to print out a stack trace in case of Nix expression evaluation errors.
+
+
+
+
+ --chroot
+
+ Chroot into given installation. Any additional arguments passed are going to be executed inside the chroot.
+
+
+
+
+
+ --help
+
+ Synonym for man nixos-install .
+
+
+
+
+
+
+
Examples
@@ -72,6 +186,7 @@ $ mount /dev/sda1 /mnt
$ nixos-generate-config --root /mnt
$ # edit /mnt/etc/nixos/configuration.nix
$ nixos-install
+$ reboot
diff --git a/nixos/doc/manual/man-nixos-option.xml b/nixos/doc/manual/man-nixos-option.xml
index 7952847d4db..2875336c67e 100644
--- a/nixos/doc/manual/man-nixos-option.xml
+++ b/nixos/doc/manual/man-nixos-option.xml
@@ -17,11 +17,6 @@
nixos-option
-
- -v
- -d
- -l
-
option.name
@@ -31,50 +26,13 @@
This command evaluates the configuration specified in
/etc/nixos/configuration.nix and returns the properties
-of the option name given as argument. By default, it returns the value of
-the option.
+of the option name given as argument.
When the option name is not an option, the command prints the list of
attributes contained in the attribute set.
-Options
-
-This command accepts the following options:
-
-
-
-
- --value , -v
-
- Returns the value of the option. This is the default operation
- if no other options are defined.
-
-
-
-
- --description , -d
-
- Return the default value, the example and the description of the
- option when available.
-
-
-
-
- --lookup , -l
-
- Return the locations where the option is declared and where it
- is defined. This is extremely useful to find sources of errors in
- your configuration.
-
-
-
-
-
-
-
-
Environment
@@ -103,27 +61,21 @@ grub
initScript
$ nixos-option boot.loader.grub.enable
-true
+Value:
+true
-Prints option information:
+Default:
+true
-$ nixos-option -d networking.hostName
-Default: "nixos"
Description:
-The name of the machine. Leave it empty if you want to obtain
-it from a DHCP server (if using DHCP).
+Whether to enable the GNU GRUB boot loader.
-Find the locations which are declaring and defining an option:
-
-$ nixos-option -l hardware.firmware
Declared by:
- /mnt/data/nix-sources/nixos/modules/services/hardware/udev.nix
+ "/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix"
Defined by:
- /path/to/nixpkgs/nixos/modules/system/boot/kernel.nix
- /path/to/nixpkgs/nixos/modules/hardware/network/rt73.nix
- /path/to/nixpkgs/nixos/modules/hardware/network/intel-3945abg.nix
- /path/to/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix
+ "/nix/var/nix/profiles/per-user/root/channels/nixos/nixpkgs/nixos/modules/system/boot/loader/grub/grub.nix"
+
diff --git a/nixos/doc/manual/man-nixos-rebuild.xml b/nixos/doc/manual/man-nixos-rebuild.xml
index afc159dbd5d..c529737c3bf 100644
--- a/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/nixos/doc/manual/man-nixos-rebuild.xml
@@ -1,7 +1,7 @@
-
+
nixos-rebuild
8
@@ -22,7 +22,8 @@
boot
test
build
- dry-run
+ dry-build
+ dry-activate
build-vm
build-vm-with-bootloader
@@ -114,10 +115,22 @@ $ nix-build /path/to/nixpkgs/nixos -A system
- dry-run
+ dry-build
- Simply show what store paths would be built or downloaded
- by any of the operations above.
+ Show what store paths would be built or downloaded by any
+ of the operations above, but otherwise do nothing.
+
+
+
+
+ dry-activate
+
+ Build the new configuration, but instead of activating it,
+ show what changes would be performed by the activation (i.e. by
+ nixos-rebuild test ). For
+ instance, this command will print which systemd units would be
+ restarted. The list of changes is not guaranteed to be
+ complete.
diff --git a/nixos/doc/manual/man-pages.xml b/nixos/doc/manual/man-pages.xml
index 467864e208b..97a2c16d406 100644
--- a/nixos/doc/manual/man-pages.xml
+++ b/nixos/doc/manual/man-pages.xml
@@ -15,7 +15,7 @@
- 2007-2013
+ 2007-2015
Eelco Dolstra
diff --git a/nixos/doc/manual/manual.xml b/nixos/doc/manual/manual.xml
index a3ad76209ac..f6aedfd6b66 100644
--- a/nixos/doc/manual/manual.xml
+++ b/nixos/doc/manual/manual.xml
@@ -32,6 +32,7 @@
+
diff --git a/nixos/doc/manual/options-to-docbook.xsl b/nixos/doc/manual/options-to-docbook.xsl
index e81a1dc356e..af9eb0e48fb 100644
--- a/nixos/doc/manual/options-to-docbook.xsl
+++ b/nixos/doc/manual/options-to-docbook.xsl
@@ -34,6 +34,14 @@
select="attr[@name = 'description']/string/@value" />
+
+
+ Type:
+
+
+
+
+
Default:
diff --git a/nixos/doc/manual/release-notes/release-notes.xml b/nixos/doc/manual/release-notes/release-notes.xml
index fb82d5adcef..a988a5b0199 100644
--- a/nixos/doc/manual/release-notes/release-notes.xml
+++ b/nixos/doc/manual/release-notes/release-notes.xml
@@ -7,10 +7,12 @@
Release Notes
-This section lists the release notes for each stable version of NixOS.
+This section lists the release notes for each stable version of NixOS
+and current unstable revision.
-
+
+
diff --git a/nixos/doc/manual/release-notes/rl-1410.xml b/nixos/doc/manual/release-notes/rl-1410.xml
deleted file mode 100644
index 09da15ce236..00000000000
--- a/nixos/doc/manual/release-notes/rl-1410.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-Release 14.10 (“Caterpillar”, 2014/10/??)
-
-When upgrading from a previous release, please be aware of the
-following incompatible changes:
-
-
-
- The host side of a container virtual Ethernet pair
- is now called ve-container-name
- rather than c-container-name .
-
-
-
-
-
-
\ No newline at end of file
diff --git a/nixos/doc/manual/release-notes/rl-1412.xml b/nixos/doc/manual/release-notes/rl-1412.xml
new file mode 100644
index 00000000000..36ae48af759
--- /dev/null
+++ b/nixos/doc/manual/release-notes/rl-1412.xml
@@ -0,0 +1,177 @@
+
+
+Release 14.12 (“Caterpillar”, 2014/12/30)
+
+In addition to numerous new and upgraded packages, this release has the following highlights:
+
+
+
+Systemd has been updated to version 217, which has numerous
+ improvements.
+
+
+Nix has been updated to 1.8.
+
+NixOS is now based on Glibc 2.20.
+
+KDE has been updated to 4.14.
+
+The default Linux kernel has been updated to 3.14.
+
+If users.mutableUsers is enabled (the
+default), changes made to the declaration of a user or group will be
+correctly realised when running nixos-rebuild . For
+instance, removing a user specification from
+configuration.nix will cause the actual user
+account to be deleted. If users.mutableUsers is
+disabled, it is no longer necessary to specify UIDs or GIDs; if
+omitted, they are allocated dynamically.
+
+
+
+Following new services were added since the last release:
+
+
+atftpd
+bosun
+bspwm
+chronos
+collectd
+consul
+cpuminer-cryptonight
+crashplan
+dnscrypt-proxy
+docker-registry
+docker
+etcd
+fail2ban
+fcgiwrap
+fleet
+fluxbox
+gdm
+geoclue2
+gitlab
+gitolite
+gnome3.gnome-documents
+gnome3.gnome-online-miners
+gnome3.gvfs
+gnome3.seahorse
+hbase
+i2pd
+influxdb
+kubernetes
+liquidsoap
+lxc
+mailpile
+mesos
+mlmmj
+monetdb
+mopidy
+neo4j
+nsd
+openntpd
+opentsdb
+openvswitch
+parallels-guest
+peerflix
+phd
+polipo
+prosody
+radicale
+redmine
+riemann
+scollector
+seeks
+siproxd
+strongswan
+tcsd
+teamspeak3
+thermald
+torque/mrom
+torque/server
+uhub
+unifi
+znc
+zookeeper
+
+
+
+When upgrading from a previous release, please be aware of the
+following incompatible changes:
+
+
+
+The default version of Apache httpd is now 2.4. If
+you use the extraConfig option to pass literal
+Apache configuration text, you may need to update it — see Apache’s
+documentation for details. If you wish to continue to use
+httpd 2.2, add the following line to your NixOS configuration:
+
+
+services.httpd.package = pkgs.apacheHttpd_2_2;
+
+
+
+
+PHP 5.3 has been removed because it is no longer
+supported by the PHP project. A migration guide is
+available.
+
+The host side of a container virtual Ethernet pair
+is now called ve-container-name
+rather than c-container-name .
+
+GNOME 3.10 support has been dropped. The default GNOME version is now 3.12.
+
+VirtualBox has been upgraded to 4.3.20 release. Users
+may be required to run rm -rf /tmp/.vbox* . The line
+imports = [ <nixpkgs/nixos/modules/programs/virtualbox.nix> ] is
+no longer necessary, use services.virtualboxHost.enable =
+true instead.
+
+Also, hardening mode is now enabled by default, which means that unless you want to use
+USB support, you no longer need to be a member of the vboxusers group.
+
+
+Chromium has been updated to 39.0.2171.65. enablePepperPDF is now enabled by default.
+chromium*Wrapper packages no longer exist, because upstream removed NSAPI support.
+chromium-stable has been renamed to chromium .
+
+
+Python packaging documentation is now part of nixpkgs manual. To override
+the python packages available to a custom python you now use pkgs.pythonFull.buildEnv.override
+instead of pkgs.pythonFull.override .
+
+
+boot.resumeDevice = "8:6" is no longer supported. Most users will
+want to leave it undefined, which takes the swap partitions automatically. There is an evaluation
+assertion to ensure that the string starts with a slash.
+
+
+The system-wide default timezone for NixOS installations
+changed from CET to UTC . To choose
+a different timezone for your system, configure
+time.timeZone in
+configuration.nix . A fairly complete list of possible
+values for that setting is available at .
+
+GNU screen has been updated to 4.2.1, which breaks
+the ability to connect to sessions created by older versions of
+screen.
+
+The Intel GPU driver was updated to the 3.x prerelease
+version (used by most distributions) and supports DRI3
+now.
+
+
+
+
+
+
diff --git a/nixos/doc/manual/release-notes/rl-unstable.xml b/nixos/doc/manual/release-notes/rl-unstable.xml
new file mode 100644
index 00000000000..34ffe1d6d32
--- /dev/null
+++ b/nixos/doc/manual/release-notes/rl-unstable.xml
@@ -0,0 +1,41 @@
+
+
+Unstable revision
+
+In addition to numerous new and upgraded packages, this release has the following highlights:
+
+
+
+
+Following new services were added since the last release:
+
+
+
+
+When upgrading from a previous release, please be aware of the
+following incompatible changes:
+
+
+
+Steam now doesn't need root rights to work. Instead of using
+*-steam-chrootenv , you should now just run steam .
+steamChrootEnv package was renamed to steam ,
+and old steam package -- to steamOriginal .
+
+
+CMPlayer has been renamed to bomi upstream. Package cmplayer
+was accordingly renamed to bomi
+
+
+
+
+
+
diff --git a/nixos/gui/README b/nixos/gui/README
deleted file mode 100644
index c038314a0dc..00000000000
--- a/nixos/gui/README
+++ /dev/null
@@ -1,16 +0,0 @@
-This file should become a nix expression. (see modules/installer/tools/tools.nix)
-
-you need to:
-- download the latest jQuery from and copy it to chrome/content:
- http://code.jquery.com/jquery-1.5.2.js
-
-- install 'xulrunner' with nix:
- nix-env -Ai nixpkgs_sys.firefox40Pkgs.xulrunner
-
-- make sure nixos-option in your path
-
-- have /etc/nixos/nixpkgs
-- have /etc/nixos/nixos
-
-run it:
-- xulrunner /etc/nixos/nixos/gui/application.ini -jsconsole
diff --git a/nixos/gui/application.ini b/nixos/gui/application.ini
deleted file mode 100644
index d2494a1a5cd..00000000000
--- a/nixos/gui/application.ini
+++ /dev/null
@@ -1,36 +0,0 @@
-[App]
-;
-; This field specifies your organization's name. This field is recommended,
-; but optional.
-Vendor=NixOS
-;
-; This field specifies your application's name. This field is required.
-Name=NixOS-gui
-;
-; This field specifies your application's version. This field is optional.
-Version=0.1
-;
-; This field specifies your application's build ID (timestamp). This field is
-; required.
-BuildID=20110424
-;
-; This field specifies a compact copyright notice for your application. This
-; field is optional.
-;Copyright=
-
-;
-; This ID is just an example. Every XUL app ought to have it's own unique ID.
-; You can use the microsoft "guidgen" or "uuidgen" tools, or go on
-; irc.mozilla.org and /msg botbot uuid. This field is optional.
-;ID=
-
-[Gecko]
-;
-; This field is required. It specifies the minimum Gecko version that this
-; application requires.
-MinVersion=1.9a5
-;
-; This field is optional. It specifies the maximum Gecko version that this
-; application requires. It should be specified if your application uses
-; unfrozen interfaces.
-MaxVersion=2.*
diff --git a/nixos/gui/chrome.manifest b/nixos/gui/chrome.manifest
deleted file mode 100644
index 865d6a88fb4..00000000000
--- a/nixos/gui/chrome.manifest
+++ /dev/null
@@ -1 +0,0 @@
-manifest chrome/chrome.manifest
diff --git a/nixos/gui/chrome/chrome.manifest b/nixos/gui/chrome/chrome.manifest
deleted file mode 100644
index 775445ee17b..00000000000
--- a/nixos/gui/chrome/chrome.manifest
+++ /dev/null
@@ -1 +0,0 @@
-content nixos-gui content/
diff --git a/nixos/gui/chrome/content/io.js b/nixos/gui/chrome/content/io.js
deleted file mode 100644
index 8d9c8c17365..00000000000
--- a/nixos/gui/chrome/content/io.js
+++ /dev/null
@@ -1,137 +0,0 @@
-
-function inspect(obj, maxLevels, level)
-{
- var str = '', type, msg;
-
- // Start Input Validations
- // Don't touch, we start iterating at level zero
- if(level == null) level = 0;
-
- // At least you want to show the first level
- if(maxLevels == null) maxLevels = 1;
- if(maxLevels < 1)
- return 'Error: Levels number must be > 0 ';
-
- // We start with a non null object
- if(obj == null)
- return 'Error: Object NULL ';
- // End Input Validations
-
- // Each Iteration must be indented
- str += '';
-
- // Start iterations for all objects in obj
- for(property in obj)
- {
- try
- {
- // Show "property" and "type property"
- type = typeof(obj[property]);
- str += '(' + type + ') ' + property +
- ( (obj[property]==null)?(': null '):('')) + ' ';
-
- // We keep iterating if this property is an Object, non null
- // and we are inside the required number of levels
- if((type == 'object') && (obj[property] != null) && (level+1 < maxLevels))
- str += inspect(obj[property], maxLevels, level+1);
- }
- catch(err)
- {
- // Is there some properties in obj we can't access? Print it red.
- if(typeof(err) == 'string') msg = err;
- else if(err.message) msg = err.message;
- else if(err.description) msg = err.description;
- else msg = 'Unknown';
-
- str += '(Error) ' + property + ': ' + msg +' ';
- }
- }
-
- // Close indent
- str += ' ';
-
- return str;
-}
-
-// Run xulrunner application.ini -jsconsole -console, to see messages.
-function log(str)
-{
- Components.classes['@mozilla.org/consoleservice;1']
- .getService(Components.interfaces.nsIConsoleService)
- .logStringMessage(str);
-}
-
-function makeTempFile(prefix)
-{
- var file = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("TmpD", Components.interfaces.nsIFile);
- file.append(prefix || "xulrunner");
- file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0664);
- return file;
-}
-
-function writeToFile(file, data)
-{
- // file is nsIFile, data is a string
- var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Components.interfaces.nsIFileOutputStream);
-
- // use 0x02 | 0x10 to open file for appending.
- foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
- foStream.write(data, data.length);
- foStream.close();
-}
-
-function readFromFile(file)
-{
- // |file| is nsIFile
- var data = "";
- var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Components.interfaces.nsIFileInputStream);
- var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Components.interfaces.nsIScriptableInputStream);
- fstream.init(file, -1, 0, 0);
- sstream.init(fstream);
-
- var str = sstream.read(4096);
- while (str.length > 0) {
- data += str;
- str = sstream.read(4096);
- }
-
- sstream.close();
- fstream.close();
-
- return data;
-}
-
-function runProgram(commandLine)
-{
- // create an nsILocalFile for the executable
- var file = Components.classes["@mozilla.org/file/local;1"]
- .createInstance(Components.interfaces.nsILocalFile);
- file.initWithPath("/bin/sh");
-
- // create an nsIProcess
- var process = Components.classes["@mozilla.org/process/util;1"]
- .createInstance(Components.interfaces.nsIProcess);
- process.init(file);
-
- // Run the process.
- // If first param is true, calling thread will be blocked until
- // called process terminates.
- // Second and third params are used to pass command-line arguments
- // to the process.
- var args = ["-c", commandLine];
- process.run(true, args, args.length);
-}
-
-// only for testing...
-function testIO()
-{
- var f = makeTempFile();
- writeToFile(f, "essai\ntest");
- alert(readFromFile(f));
- runProgram("zenity --info");
-}
diff --git a/nixos/gui/chrome/content/main.js b/nixos/gui/chrome/content/main.js
deleted file mode 100644
index ecfc5a8c5c9..00000000000
--- a/nixos/gui/chrome/content/main.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// global variables.
-var gNixOS;
-var gOptionView;
-
-/*
-var gProgressBar;
-function setProgress(current, max)
-{
- if (gProgressBar) {
- gProgressBar.value = 100 * current / max;
- log("progress: " + gProgressBar.value + "%");
- }
- else
- log("unknow progress bar");
-}
-*/
-
-function updateTextbox(id, value)
-{
- // setting the height cause an overflow which resize the textbox to its
- // content due to its onoverflow attribute.
- $(id).attr("value", value).attr("height", 1);
-};
-
-function updatePanel(options)
-{
- log("updatePanel: " + options.length);
- if (options.length == 0)
- return;
- // FIXME: ignore the rest of the selection for now.
- var o = options[0];
- $("#name").attr("label", o.path);
-
- if (o.typename != null)
- $("#typename").attr("label", o.typename);
- else
- $("#typename").attr("label", "");
-
- $("#desc").text(o.description);
-
- if (o.value != null)
- updateTextbox("#val", o.value);
- else
- updateTextbox("#val", "");
-
- if (o.defaultValue != null)
- updateTextbox("#def", o.defaultValue);
- else
- updateTextbox("#def", "");
-
- if (o.example != null)
- updateTextbox("#exp", o.example);
- else
- updateTextbox("#exp", "");
-
- updateTextbox("#decls", o.declarations.join("\n"));
- updateTextbox("#defs", o.definitions.join("\n"));
-}
-
-
-function onload()
-{
- var optionTree = document.getElementById("option-tree");
- // gProgressBar = document.getElementById("progress-bar");
- // setProgress(0, 1);
-
- gNixOS = new NixOS();
- gOptionView = new OptionView(gNixOS.option, updatePanel);
- optionTree.view = gOptionView;
-}
diff --git a/nixos/gui/chrome/content/myviewer.xul b/nixos/gui/chrome/content/myviewer.xul
deleted file mode 100644
index 2aeb9391d07..00000000000
--- a/nixos/gui/chrome/content/myviewer.xul
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/nixos/gui/chrome/content/nixos.js b/nixos/gui/chrome/content/nixos.js
deleted file mode 100644
index 63a3c16a573..00000000000
--- a/nixos/gui/chrome/content/nixos.js
+++ /dev/null
@@ -1,255 +0,0 @@
-
-function NixOS () {
- var env = Components.classes["@mozilla.org/process/environment;1"].
- getService(Components.interfaces.nsIEnvironment);
-
- if (env.exists("NIXOS"))
- this.nixos = env.get("NIXOS");
- if (env.exists("NIXOS_CONFIG"))
- this.config = env.get("NIXOS_CONFIG");
- if (env.exists("NIXPKGS"))
- this.nixpkgs = env.get("NIXPKGS");
- if (env.exists("mountPoint"))
- this.root = env.get("mountPoint");
- if (env.exists("NIXOS_OPTION"))
- this.optionBin = env.get("NIXOS_OPTION");
- this.option = new Option("options", this, null);
-};
-
-NixOS.prototype = {
- root: "",
- nixos: "/etc/nixos/nixos",
- nixpkgs: "/etc/nixos/nixpkgs",
- config: "/etc/nixos/configuration.nix",
- instantiateBin: "/run/current-system/sw/bin/nix-instantiate",
- optionBin: "/run/current-system/sw/bin/nixos-option",
- tmpFile: "nixos-gui",
- option: null
-};
-
-function Option (name, context, parent) {
- this.name = name;
- this.context_ = context;
- if (parent == null)
- this.path = "";
- else if (parent.path == "")
- this.path = name;
- else
- this.path = parent.path + "." + name;
-};
-
-Option.prototype = {
- load: function () {
- var env = "";
- env += "'NIXOS=" + this.context_.root + this.context_.nixos + "' ";
- env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
- env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
- var out = makeTempFile(this.context_.tmpFile);
- var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
- var args = " --xml " + this.path;
-
- runProgram(/*env + */ prog + args);
- var xml = readFromFile(out);
- out.remove(false);
-
- // jQuery does a stack overflow when converting a huge XML to a DOM.
- var dom = DOMParser().parseFromString(xml, "text/xml");
- var xmlAttrs = $("expr > attrs > attr", dom);
-
- this.isOption = xmlAttrs.first().attr("name") == "_isOption";
-
- if (!this.isOption)
- this.loadSubOptions(xmlAttrs);
- else
- this.loadOption(xmlAttrs);
- this.isLoaded = true;
- },
-
- loadSubOptions: function (xmlAttrs) {
- var cur = this;
- var attrs = new Array();
-
- xmlAttrs.each(
- function (index) {
- var name = $(this).attr("name");
- var attr = new Option(name, cur.context_, cur);
- attrs.push(attr);
- }
- );
-
- this.subOptions = attrs;
- },
-
- optionAttributeMap: {
- _isOption: function (cur, v) { },
- value: function (cur, v) { cur.value = xml2nix($(v).children().first()); },
- default: function (cur, v) { cur.defaultValue = xml2nix($(v).children().first()); },
- example: function (cur, v) { cur.example = xml2nix($(v).children().first()); },
- description: function (cur, v) { cur.description = this.string(v); },
- typename: function (cur, v) { cur.typename = this.string(v); },
- options: function (cur, v) { cur.loadSubOptions($("attrs", v).children()); },
- declarations: function (cur, v) { cur.declarations = this.pathList(v); },
- definitions: function (cur, v) { cur.definitions = this.pathList(v); },
-
- string: function (v) {
- return $(v).children("string").first().attr("value");
- },
-
- pathList: function (v) {
- var list = [];
- $(v).children("list").first().children().each(
- function (idx) {
- list.push($(this).attr("value"));
- }
- );
- return list;
- }
- },
-
-
- loadOption: function (attrs) {
- var cur = this;
-
- attrs.each(
- function (index) {
- var name = $(this).attr("name");
- log("loadOption: " + name);
- cur.optionAttributeMap[name](cur, this);
- }
- );
- },
-
- // keep the context under which this option has been used.
- context_: null,
- // name of the option.
- name: "",
- // result of nixos-option.
- value: null,
- typename: null,
- defaultValue: null,
- example: null,
- description: "",
- declarations: [],
- definitions: [],
- // path to reach this option
- path: "",
-
- // list of options accessible from here.
- isLoaded: false,
- isOption: false,
- subOptions: []
-};
-
-var xml2nix_pptable = {
- attrs: function (node, depth, pp) {
- var children = node.children().not(
- function () {
- var name = $(this).attr("name");
- return name.charAt(0) == "_";
- }
- );
- var c = 0;
- var out = "";
- out += "{";
- depth += 1;
- children.each(
- function (idx) {
- c += 1;
- out += pp.indent(depth);
- out += pp.dispatch($(this), depth, pp);
- }
- );
- depth -= 1;
- if (c > 0)
- out += this.indent(depth);
- else
- out += " ";
- out += "}";
- return out;
- },
- list: function (node, depth, pp) {
- var children = node.children();
- var c = 0;
- var out = "";
- out += "[";
- depth += 1;
- children.each(
- function (idx) {
- c += 1;
- out += pp.indent(depth);
- out += pp.dispatch($(this), depth, pp);
- }
- );
- depth -= 1;
- if (c > 0)
- out += this.indent(depth);
- else
- out += " ";
- out += "]";
- return out;
- },
- attr: function (node, depth, pp) {
- var name = node.attr("name");
- var out = "";
- var val = "";
- out += name + " = ";
- depth += 1;
- val = pp.dispatch(node.children().first(), depth, pp);
- out += val;
- depth -= 1;
- out += ";";
- return out;
- },
- string: function (node, depth, pp) {
- return "\"" + node.attr("value") + "\"";
- },
- path: function (node, depth, pp) {
- return node.attr("value");
- },
- bool: function (node, depth, pp) {
- return node.attr("value");
- },
- "int": function (node, depth, pp) {
- return node.attr("value");
- },
- null: function (node, depth, pp) {
- return "null";
- },
- derivation: function (node, depth, pp) {
- return "";
- },
- function: function (node, depth, pp) {
- return "";
- },
- unevaluated: function (node, depth, pp) {
- return "";
- },
-
- dispatch: function (node, depth, pp) {
- for (var key in pp)
- {
- if(node.is(key))
- {
- // log(this.indent(depth) + "dispatch: " + key);
- var out = pp[key](node, depth, pp);
- // log(this.indent(depth) + "dispatch: => " + out);
- return out;
- }
- }
- return "";
- },
- indent: function (depth) {
- var ret = "\n";
- while (depth--)
- ret += " ";
- return ret;
- }
-};
-
-function xml2nix(node) {
- var depth = 0;
- var pp = xml2nix_pptable;
- var out = pp.dispatch(node, depth, pp);
- // log("pretty:\n" + out);
- return out;
-}
diff --git a/nixos/gui/chrome/content/optionView.js b/nixos/gui/chrome/content/optionView.js
deleted file mode 100644
index 0d093740fe2..00000000000
--- a/nixos/gui/chrome/content/optionView.js
+++ /dev/null
@@ -1,242 +0,0 @@
-// extend NixOS options to handle the Tree View. Should be better to keep a
-// separation of concern here.
-
-Option.prototype.tv_opened = false;
-Option.prototype.tv_size = 1;
-
-Option.prototype.tv_open = function () {
- this.tv_opened = true;
- this.tv_size = 1;
-
- // load an option if it is not loaded yet, and initialize them to be
- // read by the Option view.
- if (!this.isLoaded)
- this.load();
-
- // If this is not an option, then add it's lits of sub-options size.
- if (!this.isOption)
- {
- for (var i = 0; i < this.subOptions.length; i++)
- this.tv_size += this.subOptions[i].tv_size;
- }
-};
-
-Option.prototype.tv_close = function () {
- this.tv_opened = false;
- this.tv_size = 1;
-};
-
-
-
-
-function OptionView (root, selCallback) {
- root.tv_open();
- this.rootOption = root;
- this.selCallback = selCallback;
-}
-
-OptionView.prototype = {
- rootOption: null,
- selCallback: null,
-
- // This function returns the path to option which is at the specified row.
- reach_cache: null,
- reachRow: function (row) {
- var o = this.rootOption; // Current option.
- var r = 0; // Number of rows traversed.
- var c = 0; // Child index.
- var path = [{ row: r, opt: o }]; // new Array();
- // hypothesis: this.rootOption.tv_size is always open and bigger than
-
- // Use the previous returned value to avoid making to many checks and to
- // optimize for frequent access of near rows.
- if (this.reach_cache != null)
- {
- for (var i = this.reach_cache.length - 2; i >= 0; i--) {
- var p = this.reach_cache[i];
- // If we will have to go the same path.
- if (row >= p.row && row < p.row + p.opt.tv_size)
- {
- path.unshift(p);
- r = path[0].row;
- o = path[0].opt;
- }
- else
- break;
- };
- }
-
- while (r != row)
- {
- // Go deeper in the child which contains the requested row. The
- // tv_size contains the size of the tree starting from each option.
- c = 0;
- while (c < o.subOptions.length && r + o.subOptions[c].tv_size < row)
- {
- r += o.subOptions[c].tv_size;
- c += 1;
- }
- if (c < o.subOptions.length && r + o.subOptions[c].tv_size >= row)
- {
- // Count the current option as a row.
- o = o.subOptions[c];
- r += 1;
- }
- else
- alert("WTF: " + o.name + " ask: " + row + " children: " + o.subOptions + " c: " + c);
- path.unshift({ row: r, opt: o });
- }
-
- this.reach_cache = path;
- return path;
- },
-
- // needs to return true if there is a /row/ at the same level /after/ a
- // given row.
- hasNextSibling: function(row, after) {
- log("sibling " + row + " after " + after);
- var path = reachRow(row);
- if (path.length > 1)
- {
- var last = path[1].row + path[1].opt.tv_size;
- // Has a next sibling if the row is not over the size of the
- // parent and if the current one is not the last child.
- return after + 1 < last && path[0].row + path[0].opt.tv_size < last;
- }
- else
- // The top-level option has no sibling.
- return false;
- },
-
- // Does the current row contain any sub-options?
- isContainer: function(row) {
- return !this.reachRow(row)[0].opt.isOption;
- },
- isContainerEmpty: function(row) {
- return this.reachRow(row)[0].opt.subOptions.length == 0;
- },
- isContainerOpen: function(row) {
- return this.reachRow(row)[0].opt.tv_opened;
- },
-
- // Open or close an option.
- toggleOpenState: function (row) {
- var path = this.reachRow(row);
- var delta = -path[0].opt.tv_size;
- if (path[0].opt.tv_opened)
- path[0].opt.tv_close();
- else
- path[0].opt.tv_open();
- delta += path[0].opt.tv_size;
-
- // Parents are alreay opened, but we need to update the tv_size
- // counters. Thus we have to invalidate the reach cache.
- this.reach_cache = null;
- for (var i = 1; i < path.length; i++)
- path[i].opt.tv_open();
-
- this.tree.rowCountChanged(row + 1, delta);
- },
-
- // Return the identation level of the option at the line /row/. The
- // top-level level is 0.
- getLevel: function(row) {
- return this.reachRow(row).length - 1;
- },
-
- // Obtain the index of a parent row. If there is no parent row,
- // returns -1.
- getParentIndex: function(row) {
- var path = this.reachRow(row);
- if (path.length > 1)
- return path[1].row;
- else
- return -1;
- },
-
-
- // Return the content of each row base on the column name.
- getCellText: function(row, column) {
- if (column.id == "opt-name")
- return this.reachRow(row)[0].opt.name;
- if (column.id == "dbg-size")
- return this.reachRow(row)[0].opt.tv_size;
- return "";
- },
-
- // We have no column with images.
- getCellValue: function(row, column) { },
-
-
- isSelectable: function(row, column) { return true; },
-
- // Get the selection out of the tree and give options to the call back
- // function.
- selectionChanged: function() {
- if (this.selCallback == null)
- return;
- var opts = [];
- var start = new Object();
- var end = new Object();
- var numRanges = this.tree.view.selection.getRangeCount();
-
- for (var t = 0; t < numRanges; t++) {
- this.tree.view.selection.getRangeAt(t,start,end);
- for (var v = start.value; v <= end.value; v++) {
- var opt = this.reachRow(v)[0].opt;
- if (!opt.isLoaded)
- opt.load();
- if (opt.isOption)
- opts.push(opt);
-
- // FIXME: no need to make things slowing down, because our current
- // callback do not handle multiple option display.
- if (!opts.empty)
- break;
- }
- // FIXME: no need to make things slowing down, because our current
- // callback do not handle multiple option display.
- if (!opts.empty)
- break;
- }
-
- if (!opts.empty)
- this.selCallback(opts);
- },
-
- set rowCount(c) { throw "rowCount is a readonly property"; },
- get rowCount() { return this.rootOption.tv_size; },
-
- // refuse drag-n-drop of options.
- canDrop: function (index, orientation, dataTransfer) { return false; },
- drop: function (index, orientation, dataTransfer) { },
-
- // ?
- getCellProperties: function(row, column, prop) { },
- getColumnProperties: function(column, prop) { },
- getRowProperties: function(row, prop) { },
- getImageSrc: function(row, column) { },
-
- // No progress columns are used.
- getProgressMode: function(row, column) { },
-
- // Do not add options yet.
- isEditable: function(row, column) { return false; },
- setCellValue: function(row, column, value) { },
- setCellText: function(row, column, value) { },
-
- // ...
- isSeparator: function(index) { return false; },
- isSorted: function() { return false; },
- performAction: function(action) { },
- performActionOnCell: function(action, row, column) { },
- performActionOnRow: function(action, row) { }, // ??
-
- // ??
- cycleCell: function (row, col) { },
- cycleHeader: function(col) { },
-
- selection: null,
- tree: null,
- setTree: function(tree) { this.tree = tree; }
-};
diff --git a/nixos/gui/components/clh.js b/nixos/gui/components/clh.js
deleted file mode 100644
index fd85422d6c8..00000000000
--- a/nixos/gui/components/clh.js
+++ /dev/null
@@ -1,154 +0,0 @@
-const nsIAppShellService = Components.interfaces.nsIAppShellService;
-const nsISupports = Components.interfaces.nsISupports;
-const nsICategoryManager = Components.interfaces.nsICategoryManager;
-const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
-const nsICommandLine = Components.interfaces.nsICommandLine;
-const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
-const nsIFactory = Components.interfaces.nsIFactory;
-const nsIModule = Components.interfaces.nsIModule;
-const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
-
-// CHANGEME: to the chrome URI of your extension or application
-const CHROME_URI = "chrome://nixos-gui/content/myviewer.xul";
-
-// CHANGEME: change the contract id, CID, and category to be unique
-// to your application.
-const clh_contractID = "@mozilla.org/commandlinehandler/general-startup;1?type=myapp";
-
-// use uuidgen to generate a unique ID
-const clh_CID = Components.ID("{2991c315-b871-42cd-b33f-bfee4fcbf682}");
-
-// category names are sorted alphabetically. Typical command-line handlers use a
-// category that begins with the letter "m".
-const clh_category = "m-myapp";
-
-/**
- * Utility functions
- */
-
-/**
- * Opens a chrome window.
- * @param aChromeURISpec a string specifying the URI of the window to open.
- * @param aArgument an argument to pass to the window (may be null)
- */
-function openWindow(aChromeURISpec, aArgument)
-{
- var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
- getService(Components.interfaces.nsIWindowWatcher);
- ww.openWindow(null, aChromeURISpec, "_blank",
- "chrome,menubar,toolbar,status,resizable,dialog=no",
- aArgument);
-}
-
-/**
- * The XPCOM component that implements nsICommandLineHandler.
- * It also implements nsIFactory to serve as its own singleton factory.
- */
-const myAppHandler = {
- /* nsISupports */
- QueryInterface : function clh_QI(iid)
- {
- if (iid.equals(nsICommandLineHandler) ||
- iid.equals(nsIFactory) ||
- iid.equals(nsISupports))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- },
-
- /* nsICommandLineHandler */
-
- handle : function clh_handle(cmdLine)
- {
- openWindow(CHROME_URI, cmdLine);
- cmdLine.preventDefault = true;
- },
-
- // CHANGEME: change the help info as appropriate, but
- // follow the guidelines in nsICommandLineHandler.idl
- // specifically, flag descriptions should start at
- // character 24, and lines should be wrapped at
- // 72 characters with embedded newlines,
- // and finally, the string should end with a newline
- helpInfo : " Open the file in the viewer\n",
-
- /* nsIFactory */
-
- createInstance : function clh_CI(outer, iid)
- {
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return this.QueryInterface(iid);
- },
-
- lockFactory : function clh_lock(lock)
- {
- /* no-op */
- }
-};
-
-/**
- * The XPCOM glue that implements nsIModule
- */
-const myAppHandlerModule = {
- /* nsISupports */
- QueryInterface : function mod_QI(iid)
- {
- if (iid.equals(nsIModule) ||
- iid.equals(nsISupports))
- return this;
-
- throw Components.results.NS_ERROR_NO_INTERFACE;
- },
-
- /* nsIModule */
- getClassObject : function mod_gch(compMgr, cid, iid)
- {
- if (cid.equals(clh_CID))
- return myAppHandler.QueryInterface(iid);
-
- throw Components.results.NS_ERROR_NOT_REGISTERED;
- },
-
- registerSelf : function mod_regself(compMgr, fileSpec, location, type)
- {
- compMgr.QueryInterface(nsIComponentRegistrar);
-
- compMgr.registerFactoryLocation(clh_CID,
- "myAppHandler",
- clh_contractID,
- fileSpec,
- location,
- type);
-
- var catMan = Components.classes["@mozilla.org/categorymanager;1"].
- getService(nsICategoryManager);
- catMan.addCategoryEntry("command-line-handler",
- clh_category,
- clh_contractID, true, true);
- },
-
- unregisterSelf : function mod_unreg(compMgr, location, type)
- {
- compMgr.QueryInterface(nsIComponentRegistrar);
- compMgr.unregisterFactoryLocation(clh_CID, location);
-
- var catMan = Components.classes["@mozilla.org/categorymanager;1"].
- getService(nsICategoryManager);
- catMan.deleteCategoryEntry("command-line-handler", clh_category);
- },
-
- canUnload : function (compMgr)
- {
- return true;
- }
-};
-
-/* The NSGetModule function is the magic entry point that XPCOM uses to find what XPCOM objects
- * this component provides
- */
-function NSGetModule(comMgr, fileSpec)
-{
- return myAppHandlerModule;
-}
diff --git a/nixos/gui/defaults/preferences/myviewer-prefs.js b/nixos/gui/defaults/preferences/myviewer-prefs.js
deleted file mode 100644
index e10fa18c0d8..00000000000
--- a/nixos/gui/defaults/preferences/myviewer-prefs.js
+++ /dev/null
@@ -1,11 +0,0 @@
-pref("toolkit.defaultChromeURI", "chrome://nixos-gui/content/myviewer.xul");
-pref("general.useragent.extra.myviewer", "NixOS gui/0.0");
-
-/* debugging prefs */
-pref("browser.dom.window.dump.enabled", true); // enable output to stderr
-pref("javascript.options.showInConsole", true); // show javascript errors from chrome: files in the jsconsole
-pref("javascript.options.strict", true); // show javascript strict warnings in the jsconsole
-
-/* disable xul cache so that modifications to chrome: files apply without restarting xulrunner */
-pref("nglayout.debug.disable_xul_cache", true);
-pref("nglayout.debug.disable_xul_fastload", true);
diff --git a/nixos/lib/build-vms.nix b/nixos/lib/build-vms.nix
index 498c0a37783..d0c9e7c6d23 100644
--- a/nixos/lib/build-vms.nix
+++ b/nixos/lib/build-vms.nix
@@ -48,10 +48,11 @@ rec {
let
interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255);
interfaces = flip map interfacesNumbered ({ first, second }:
- nameValuePair "eth${toString second}"
- { ipAddress = "192.168.${toString first}.${toString m.second}";
- subnetMask = "255.255.255.0";
- });
+ nameValuePair "eth${toString second}" { ip4 =
+ [ { address = "192.168.${toString first}.${toString m.second}";
+ prefixLength = 24;
+ } ];
+ });
in
{ key = "ip-address";
config =
@@ -60,7 +61,7 @@ rec {
networking.interfaces = listToAttrs interfaces;
networking.primaryIPAddress =
- optionalString (interfaces != []) (head interfaces).value.ipAddress;
+ optionalString (interfaces != []) (head (head interfaces).value.ip4).address;
# Put the IP addresses of all VMs in this machine's
# /etc/hosts file. If a machine has multiple
@@ -69,7 +70,7 @@ rec {
# virtualisation.vlans option).
networking.extraHosts = flip concatMapStrings machines
(m': let config = (getAttr m' nodes).config; in
- optionalString (m.first != m' && config.networking.primaryIPAddress != "")
+ optionalString (config.networking.primaryIPAddress != "")
("${config.networking.primaryIPAddress} " +
"${config.networking.hostName}\n"));
diff --git a/nixos/lib/eval-config.nix b/nixos/lib/eval-config.nix
index 0fa00637a93..adacbd0863e 100644
--- a/nixos/lib/eval-config.nix
+++ b/nixos/lib/eval-config.nix
@@ -2,26 +2,51 @@
# configuration object (`config') from which we can retrieve option
# values.
-{ system ? builtins.currentSystem
-, pkgs ? null
-, baseModules ? import ../modules/module-list.nix
-, extraArgs ? {}
+# !!! Please think twice before adding to this argument list!
+# Ideally eval-config.nix would be an extremely thin wrapper
+# around lib.evalModules, so that modular systems that have nixos configs
+# as subcomponents (e.g. the container feature, or nixops if network
+# expressions are ever made modular at the top level) can just use
+# types.submodule instead of using eval-config.nix
+{ # !!! system can be set modularly, would be nice to remove
+ system ? builtins.currentSystem
+, # !!! is this argument needed any more? The pkgs argument can
+ # be set modularly anyway.
+ pkgs ? null
+, # !!! what do we gain by making this configurable?
+ baseModules ? import ../modules/module-list.nix
+, # !!! See comment about args in lib/modules.nix
+ extraArgs ? {}
, modules
-, check ? true
+, # !!! See comment about check in lib/modules.nix
+ check ? true
, prefix ? []
+, lib ? import ../../lib
}:
-let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
+let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system;
+ extraModules = let e = builtins.getEnv "NIXOS_EXTRA_MODULE_PATH";
+ in if e == "" then [] else [(import (builtins.toPath e))];
+in
-rec {
+let
+ pkgsModule = rec {
+ _file = ./eval-config.nix;
+ key = _file;
+ config = {
+ nixpkgs.system = lib.mkDefault system_;
+ _module.args.pkgs = lib.mkIf (pkgs_ != null) (lib.mkForce pkgs_);
+ };
+ };
+
+in rec {
# Merge the option definitions in all modules, forming the full
# system configuration.
- inherit (pkgs.lib.evalModules {
- inherit prefix;
- modules = modules ++ baseModules;
+ inherit (lib.evalModules {
+ inherit prefix check;
+ modules = modules ++ extraModules ++ baseModules ++ [ pkgsModule ];
args = extraArgs;
- check = check && options.environment.checkConfigurationOptions.value;
}) config options;
# These are the extra arguments passed to every module. In
@@ -32,40 +57,8 @@ rec {
# the 64-bit package anyway. However, it would be cleaner to respect
# nixpkgs.config here.
extraArgs = extraArgs_ // {
- inherit pkgs modules baseModules;
- modulesPath = ../modules;
- pkgs_i686 = import ./nixpkgs.nix { system = "i686-linux"; config.allowUnfree = true; };
- utils = import ./utils.nix pkgs;
+ inherit modules baseModules;
};
- # Import Nixpkgs, allowing the NixOS option nixpkgs.config to
- # specify the Nixpkgs configuration (e.g., to set package options
- # such as firefox.enableGeckoMediaPlayer, or to apply global
- # overrides such as changing GCC throughout the system), and the
- # option nixpkgs.system to override the platform type. This is
- # tricky, because we have to prevent an infinite recursion: "pkgs"
- # is passed as an argument to NixOS modules, but the value of "pkgs"
- # depends on config.nixpkgs.config, which we get from the modules.
- # So we call ourselves here with "pkgs" explicitly set to an
- # instance that doesn't depend on nixpkgs.config.
- pkgs =
- if pkgs_ != null
- then pkgs_
- else import ./nixpkgs.nix (
- let
- system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
- nixpkgsOptions = (import ./eval-config.nix {
- inherit system extraArgs modules prefix;
- # For efficiency, leave out most NixOS modules; they don't
- # define nixpkgs.config, so it's pointless to evaluate them.
- baseModules = [ ../modules/misc/nixpkgs.nix ../modules/config/no-x-libs.nix ];
- pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
- check = false;
- }).config.nixpkgs;
- in
- {
- inherit system;
- inherit (nixpkgsOptions) config;
- });
-
+ inherit (config._module.args) pkgs;
}
diff --git a/nixos/lib/make-iso9660-image.nix b/nixos/lib/make-iso9660-image.nix
index 5ad546e9534..b2409c6006b 100644
--- a/nixos/lib/make-iso9660-image.nix
+++ b/nixos/lib/make-iso9660-image.nix
@@ -1,4 +1,4 @@
-{ stdenv, perl, cdrkit, pathsFromGraph
+{ stdenv, perl, pathsFromGraph, xorriso, syslinux
, # The file name of the resulting ISO image.
isoName ? "cd.iso"
@@ -22,12 +22,18 @@
, # Whether this should be an efi-bootable El-Torito CD.
efiBootable ? false
+, # Wheter this should be an hybrid CD (bootable from USB as well as CD).
+ usbBootable ? false
+
, # The path (in the ISO file system) of the boot image.
bootImage ? ""
, # The path (in the ISO file system) of the efi boot image.
efiBootImage ? ""
+, # The path (outside the ISO file system) of the isohybrid-mbr image.
+ isohybridMbrImage ? ""
+
, # Whether to compress the resulting ISO image with bzip2.
compressImage ? false
@@ -38,13 +44,14 @@
assert bootable -> bootImage != "";
assert efiBootable -> efiBootImage != "";
+assert usbBootable -> isohybridMbrImage != "";
stdenv.mkDerivation {
name = "iso9660-image";
builder = ./make-iso9660-image.sh;
- buildInputs = [perl cdrkit];
+ buildInputs = [perl xorriso syslinux];
- inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable;
+ inherit isoName bootable bootImage compressImage volumeID pathsFromGraph efiBootImage efiBootable isohybridMbrImage usbBootable;
# !!! should use XML.
sources = map (x: x.source) contents;
diff --git a/nixos/lib/make-iso9660-image.sh b/nixos/lib/make-iso9660-image.sh
index 675b5bb3514..c9a37379469 100644
--- a/nixos/lib/make-iso9660-image.sh
+++ b/nixos/lib/make-iso9660-image.sh
@@ -13,6 +13,20 @@ stripSlash() {
if test "${res:0:1}" = /; then res=${res:1}; fi
}
+# Escape potential equal signs (=) with backslash (\=)
+escapeEquals() {
+ echo "$1" | sed -e 's/\\/\\\\/g' -e 's/=/\\=/g'
+}
+
+# Queues an file/directory to be placed on the ISO.
+# An entry consists of a local source path (2) and
+# a destination path on the ISO (1).
+addPath() {
+ target="$1"
+ source="$2"
+ echo "$(escapeEquals "$target")=$(escapeEquals "$source")" >> pathlist
+}
+
stripSlash "$bootImage"; bootImage="$res"
@@ -31,11 +45,20 @@ if test -n "$bootable"; then
fi
done
- bootFlags="-b $bootImage -c .boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
+ isoBootFlags="-eltorito-boot ${bootImage}
+ -eltorito-catalog .boot.cat
+ -no-emul-boot -boot-load-size 4 -boot-info-table"
+fi
+
+if test -n "$usbBootable"; then
+ usbBootFlags="-isohybrid-mbr ${isohybridMbrImage}"
fi
if test -n "$efiBootable"; then
- bootFlags="$bootFlags -eltorito-alt-boot -e $efiBootImage -no-emul-boot"
+ efiBootFlags="-eltorito-alt-boot
+ -e $efiBootImage
+ -no-emul-boot
+ -isohybrid-gpt-basdat"
fi
touch pathlist
@@ -44,14 +67,14 @@ touch pathlist
# Add the individual files.
for ((i = 0; i < ${#targets_[@]}; i++)); do
stripSlash "${targets_[$i]}"
- echo "$res=${sources_[$i]}" >> pathlist
+ addPath "$res" "${sources_[$i]}"
done
# Add the closures of the top-level store objects.
storePaths=$(perl $pathsFromGraph closure-*)
for i in $storePaths; do
- echo "${i:1}=$i" >> pathlist
+ addPath "${i:1}" "$i"
done
@@ -59,7 +82,7 @@ done
# nix-store --load-db.
if [ -n "$object" ]; then
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
- echo "nix-path-registration=nix-path-registration" >> pathlist
+ addPath "nix-path-registration" "nix-path-registration"
fi
@@ -70,22 +93,39 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
if test "$symlink" != "none"; then
mkdir -p $(dirname ./$symlink)
ln -s $object ./$symlink
- echo "$symlink=./$symlink" >> pathlist
+ addPath "$symlink" "./$symlink"
fi
done
-# !!! what does this do?
-cat pathlist | sed -e 's/=\(.*\)=\(.*\)=/\\=\1=\2\\=/' | tee pathlist.safer
-
-
mkdir -p $out/iso
-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
- $genCommand -o $out/iso/$isoName
-else
- $genCommand | bzip2 > $out/iso/$isoName.bz2
+
+xorriso="xorriso
+ -as mkisofs
+ -iso-level 3
+ -volid ${volumeID}
+ -appid nixos
+ -publisher nixos
+ -graft-points
+ -full-iso9660-filenames
+ ${isoBootFlags}
+ ${usbBootFlags}
+ ${efiBootFlags}
+ -r
+ -path-list pathlist
+ --sort-weight 0 /
+ --sort-weight 1 /isolinux" # Make sure isolinux is near the beginning of the ISO
+
+$xorriso -output $out/iso/$isoName
+
+if test -n "$usbBootable"; then
+ echo "Making image hybrid..."
+ isohybrid --uefi $out/iso/$isoName
fi
+if test -n "$compressImage"; then
+ echo "Compressing image..."
+ bzip2 $out/iso/$isoName
+fi
mkdir -p $out/nix-support
echo $system > $out/nix-support/system
diff --git a/nixos/lib/make-system-tarball.nix b/nixos/lib/make-system-tarball.nix
index 8fed9a34882..a2a0340a6bd 100644
--- a/nixos/lib/make-system-tarball.nix
+++ b/nixos/lib/make-system-tarball.nix
@@ -15,6 +15,12 @@
# store path whose closure will be copied, and `symlink' is a
# symlink to `object' that will be added to the tarball.
storeContents ? []
+
+ # Extra commands to be executed before archiving files
+, extraCommands ? ""
+
+ # Extra tar arguments
+, extraArgs ? ""
}:
stdenv.mkDerivation {
@@ -22,7 +28,7 @@ stdenv.mkDerivation {
builder = ./make-system-tarball.sh;
buildInputs = [perl xz];
- inherit fileName pathsFromGraph;
+ inherit fileName pathsFromGraph extraArgs extraCommands;
# !!! should use XML.
sources = map (x: x.source) contents;
diff --git a/nixos/lib/make-system-tarball.sh b/nixos/lib/make-system-tarball.sh
index 096d96ac1c8..e04455e889b 100644
--- a/nixos/lib/make-system-tarball.sh
+++ b/nixos/lib/make-system-tarball.sh
@@ -33,7 +33,7 @@ for i in $storePaths; do
done
-# TODO tar ruxo
+# TODO tar ruxo
# Also include a manifest of the closures in a format suitable for
# nix-store --load-db.
printRegistration=1 perl $pathsFromGraph closure-* > nix-path-registration
@@ -48,9 +48,11 @@ for ((n = 0; n < ${#objects[*]}; n++)); do
fi
done
+$extraCommands
+
mkdir -p $out/tarball
-tar cvJf $out/tarball/$fileName.tar.xz *
+tar cvJf $out/tarball/$fileName.tar.xz * $extraArgs
mkdir -p $out/nix-support
echo $system > $out/nix-support/system
diff --git a/nixos/lib/test-driver/Machine.pm b/nixos/lib/test-driver/Machine.pm
index e2bd3393d87..e0791692d3e 100644
--- a/nixos/lib/test-driver/Machine.pm
+++ b/nixos/lib/test-driver/Machine.pm
@@ -37,6 +37,10 @@ sub new {
if defined $args->{hda};
$startCommand .= "-cdrom $args->{cdrom} "
if defined $args->{cdrom};
+ $startCommand .= "-device piix3-usb-uhci -drive id=usbdisk,file=$args->{usb},if=none,readonly -device usb-storage,drive=usbdisk "
+ if defined $args->{usb};
+ $startCommand .= "-bios $args->{bios} "
+ if defined $args->{bios};
$startCommand .= $args->{qemuFlags} || "";
} else {
$startCommand = Cwd::abs_path $startCommand;
@@ -482,7 +486,7 @@ sub screenshot {
my $name = basename($filename);
$self->nest("making screenshot ‘$name’", sub {
$self->sendMonitorCommand("screendump $tmp");
- system("convert $tmp ${filename}") == 0
+ system("pnmtopng $tmp > ${filename}") == 0
or die "cannot convert screenshot";
unlink $tmp;
}, { image => $name } );
diff --git a/nixos/lib/test-driver/log2html.xsl b/nixos/lib/test-driver/log2html.xsl
index ce8a9c6de2b..0485412b4c8 100644
--- a/nixos/lib/test-driver/log2html.xsl
+++ b/nixos/lib/test-driver/log2html.xsl
@@ -9,8 +9,8 @@
-
-
+
+
Log File
diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix
index 0e23fc5d187..c14f15a1ad5 100644
--- a/nixos/lib/testing.nix
+++ b/nixos/lib/testing.nix
@@ -27,7 +27,7 @@ rec {
cp ${./test-driver/Logger.pm} $libDir/Logger.pm
wrapProgram $out/bin/nixos-test-driver \
- --prefix PATH : "${pkgs.qemu_kvm}/bin:${pkgs.vde2}/bin:${imagemagick}/bin:${coreutils}/bin" \
+ --prefix PATH : "${qemu_kvm}/bin:${vde2}/bin:${netpbm}/bin:${coreutils}/bin" \
--prefix PERL5LIB : "${lib.makePerlPath [ perlPackages.TermReadLineGnu perlPackages.XMLWriter perlPackages.IOTty ]}:$out/lib/perl5/site_perl"
'';
};
@@ -41,18 +41,20 @@ rec {
requiredSystemFeatures = [ "kvm" "nixos-test" ];
- buildInputs = [ pkgs.libxslt ];
+ buildInputs = [ libxslt ];
buildCommand =
''
mkdir -p $out/nix-support
- LOGFILE=$out/log.xml tests='eval $ENV{testScript}; die $@ if $@;' ${driver}/bin/nixos-test-driver || failed=1
+ LOGFILE=$out/log.xml tests='eval $ENV{testScript}; die $@ if $@;' ${driver}/bin/nixos-test-driver
# Generate a pretty-printed log.
xsltproc --output $out/log.html ${./test-driver/log2html.xsl} $out/log.xml
ln -s ${./test-driver/logfile.css} $out/logfile.css
ln -s ${./test-driver/treebits.js} $out/treebits.js
+ ln -s ${jquery}/js/jquery.min.js $out/
+ ln -s ${jquery-ui}/js/jquery-ui.min.js $out/
touch $out/nix-support/hydra-build-products
echo "report testlog $out log.html" >> $out/nix-support/hydra-build-products
@@ -61,8 +63,6 @@ rec {
mkdir -p $out/coverage-data
mv $i $out/coverage-data/$(dirname $(dirname $i))
done
-
- [ -z "$failed" ] || touch $out/nix-support/failed
''; # */
};
@@ -151,7 +151,7 @@ rec {
startAll;
$client->waitForUnit("multi-user.target");
${preBuild}
- $client->succeed("env -i ${pkgs.bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2");
+ $client->succeed("env -i ${bash}/bin/bash ${buildrunner} /tmp/xchg/saved-env >&2");
${postBuild}
$client->succeed("sync"); # flush all data before pulling the plug
'';
diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix
index 35c56e8c32b..7b8be2050c1 100644
--- a/nixos/lib/utils.nix
+++ b/nixos/lib/utils.nix
@@ -5,6 +5,7 @@ rec {
# Escape a path according to the systemd rules, e.g. /dev/xyzzy
# becomes dev-xyzzy. FIXME: slow.
escapeSystemdPath = s:
- replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"] (substring 1 (stringLength s) s);
+ replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
+ (if hasPrefix "/" s then substring 1 (stringLength s) s else s);
}
diff --git a/nixos/maintainers/scripts/azure/create-azure.sh b/nixos/maintainers/scripts/azure/create-azure.sh
new file mode 100755
index 00000000000..f87a88404f6
--- /dev/null
+++ b/nixos/maintainers/scripts/azure/create-azure.sh
@@ -0,0 +1,11 @@
+#! /bin/sh -e
+
+BUCKET_NAME=${BUCKET_NAME:-nixos}
+export NIX_PATH=nixpkgs=../../../..
+export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/azure-image.nix
+export TIMESTAMP=$(date +%Y%m%d%H%M)
+
+nix-build '' \
+ -A config.system.build.azureImage --argstr system x86_64-linux -o azure --option extra-binary-caches http://hydra.nixos.org -j 10
+
+azure vm image create nixos-test --location "West Europe" --md5-skip -v --os Linux azure/disk.vhd
diff --git a/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix b/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
index d9feba164a7..c0ec38bf489 100644
--- a/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
+++ b/nixos/maintainers/scripts/ec2/amazon-hvm-install-config.nix
@@ -19,12 +19,13 @@ in
{
imports = [ ./amazon-base-config.nix ];
ec2.hvm = true;
- boot.loader.grub.device = lib.mkOverride 0 "nodev";
+ boot.loader.grub.device = lib.mkOverride 0 "/dev/xvdg";
+ boot.kernelParams = [ "console=ttyS0" ];
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
+ copy_bin_and_libs ${pkgs.gawk}/bin/gawk
+ copy_bin_and_libs ${pkgs.gnused}/bin/sed
+ copy_bin_and_libs ${pkgs.utillinux}/sbin/sfdisk
cp -v ${growpart} $out/bin/growpart
'';
boot.initrd.postDeviceCommands = ''
diff --git a/nixos/maintainers/scripts/ec2/create-ebs-amis.py b/nixos/maintainers/scripts/ec2/create-ebs-amis.py
index 14607b9a367..44af56c4091 100755
--- a/nixos/maintainers/scripts/ec2/create-ebs-amis.py
+++ b/nixos/maintainers/scripts/ec2/create-ebs-amis.py
@@ -12,26 +12,35 @@ from nixops.statefile import StateFile, get_default_state_file
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('--channel', dest='channel', default="13.10", help='Channel to use')
+parser.add_argument('--channel', dest='channel', default="14.12", help='Channel to 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('--key', dest='key_name', action='store_true', help='Keypair used for HVM instance creation', default="rob")
args = parser.parse_args()
instance_type = "m3.medium" if args.hvm else "m1.small"
-ebs_size = 8 if args.hvm else 20
+if args.hvm:
+ virtualization_type = "hvm"
+ root_block = "/dev/sda1"
+ image_type = 'hvm'
+else:
+ virtualization_type = "paravirtual"
+ root_block = "/dev/sda"
+ image_type = 'ebs'
+
+ebs_size = 20
# Start a NixOS machine in the given region.
f = open("ebs-creator-config.nix", "w")
f.write('''{{
- resources.ec2KeyPairs.keypair.accessKeyId = "logicblox-dev";
+ resources.ec2KeyPairs.keypair.accessKeyId = "lb-nixos";
resources.ec2KeyPairs.keypair.region = "{0}";
machine =
{{ pkgs, ... }}:
{{
- deployment.ec2.accessKeyId = "logicblox-dev";
+ deployment.ec2.accessKeyId = "lb-nixos";
deployment.ec2.region = "{0}";
deployment.ec2.blockDeviceMapping."/dev/xvdg".size = pkgs.lib.mkOverride 10 {1};
}};
@@ -45,7 +54,7 @@ try:
except Exception:
depl = db.create_deployment()
depl.name = "ebs-creator"
-depl.auto_response = "y"
+depl.logger.set_autoresponse("y")
depl.nix_exprs = [os.path.abspath("./ebs-creator.nix"), os.path.abspath("./ebs-creator-config.nix")]
if not args.keep: depl.destroy_resources()
depl.deploy(allow_reboot=True)
@@ -66,7 +75,7 @@ m.run_command("mount {0} /mnt".format(device))
m.run_command("touch /mnt/.ebs")
m.run_command("mkdir -p /mnt/etc/nixos")
-m.run_command("nix-channel --add http://nixos.org/channels/nixos-{} nixos".format(args.channel))
+m.run_command("nix-channel --add https://nixos.org/channels/nixos-{} nixos".format(args.channel))
m.run_command("nix-channel --update")
version = m.run_command("nix-instantiate --eval-only -A lib.nixpkgsVersion ''", capture_stdout=True).split(' ')[0].replace('"','').strip()
@@ -76,10 +85,6 @@ if args.hvm:
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 -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")
@@ -87,7 +92,7 @@ else:
m.run_command("umount /mnt")
if args.hvm:
- ami_name = "nixos-{0}-x86_64-ebs-hvm".format(version)
+ ami_name = "nixos-{0}-x86_64-hvm".format(version)
description = "NixOS {0} (x86_64; EBS root; hvm)".format(version)
else:
ami_name = "nixos-{0}-x86_64-ebs".format(version)
@@ -102,58 +107,41 @@ def check():
m.connect()
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
-if args.hvm:
- instance = m._conn.run_instances( image_id="ami-5f491f36"
- , instance_type=instance_type
- , key_name=args.key_name
- , placement=m.zone
- , security_groups=["eelco-test"]).instances[0]
- nixops.util.check_wait(lambda: instance.update() == 'running', max_tries=120)
- instance.stop()
- nixops.util.check_wait(lambda: instance.update() == 'stopped', max_tries=120)
- old_root_volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': instance.id, 'attachment.device': "/dev/sda1"})[0]
- old_root_volume.detach()
- volume.detach()
- nixops.util.check_wait(lambda: volume.update() == 'available', max_tries=120)
- nixops.util.check_wait(lambda: old_root_volume.update() == 'available', max_tries=120)
- volume.attach(instance.id, '/dev/sda1')
- nixops.util.check_wait(lambda: volume.update() == 'in-use', max_tries=120)
- ami_id = m._conn.create_image(instance.id, ami_name, description)
- time.sleep(5)
- image = m._conn.get_all_images([ami_id])[0]
- nixops.util.check_wait(lambda: image.update() == 'available', max_tries=120)
- instance.terminate()
+# Create a snapshot.
+snapshot = volume.create_snapshot(description=description)
+print >> sys.stderr, "created snapshot {0}".format(snapshot.id)
-else:
- # Create a snapshot.
- snapshot = volume.create_snapshot(description=description)
- print >> sys.stderr, "created snapshot {0}".format(snapshot.id)
+nixops.util.check_wait(check, max_tries=120)
- nixops.util.check_wait(check, max_tries=120)
+m._conn.create_tags([snapshot.id], {'Name': ami_name})
- m._conn.create_tags([snapshot.id], {'Name': ami_name})
+if not args.keep: depl.destroy_resources()
- if not args.keep: depl.destroy_resources()
+# Register the image.
+aki = m._conn.get_all_images(filters={'manifest-location': 'ec2*pv-grub-hd0_1.03-x86_64*'})[0]
+print >> sys.stderr, "using kernel image {0} - {1}".format(aki.id, aki.location)
- # Register the image.
- aki = m._conn.get_all_images(filters={'manifest-location': '*pv-grub-hd0_1.03-x86_64*'})[0]
- print >> sys.stderr, "using kernel image {0} - {1}".format(aki.id, aki.location)
+block_map = BlockDeviceMapping()
+block_map[root_block] = BlockDeviceType(snapshot_id=snapshot.id, delete_on_termination=True, size=ebs_size, volume_type="gp2")
+block_map['/dev/sdb'] = BlockDeviceType(ephemeral_name="ephemeral0")
+block_map['/dev/sdc'] = BlockDeviceType(ephemeral_name="ephemeral1")
+block_map['/dev/sdd'] = BlockDeviceType(ephemeral_name="ephemeral2")
+block_map['/dev/sde'] = BlockDeviceType(ephemeral_name="ephemeral3")
- block_map = BlockDeviceMapping()
- block_map['/dev/sda'] = BlockDeviceType(snapshot_id=snapshot.id, delete_on_termination=True)
- block_map['/dev/sdb'] = BlockDeviceType(ephemeral_name="ephemeral0")
- block_map['/dev/sdc'] = BlockDeviceType(ephemeral_name="ephemeral1")
- block_map['/dev/sdd'] = BlockDeviceType(ephemeral_name="ephemeral2")
- block_map['/dev/sde'] = BlockDeviceType(ephemeral_name="ephemeral3")
-
- ami_id = m._conn.register_image(
+common_args = dict(
name=ami_name,
description=description,
architecture="x86_64",
- root_device_name="/dev/sda",
- kernel_id=aki.id,
- block_device_map=block_map)
+ root_device_name=root_block,
+ block_device_map=block_map,
+ virtualization_type=virtualization_type,
+ delete_root_volume_on_termination=True
+ )
+if not args.hvm:
+ common_args['kernel_id']=aki.id
+
+ami_id = m._conn.register_image(**common_args)
print >> sys.stderr, "registered AMI {0}".format(ami_id)
@@ -174,16 +162,16 @@ f.write(
{{
network.description = "NixOS EBS test";
- resources.ec2KeyPairs.keypair.accessKeyId = "logicblox-dev";
+ resources.ec2KeyPairs.keypair.accessKeyId = "lb-nixos";
resources.ec2KeyPairs.keypair.region = "{0}";
machine = {{ config, pkgs, resources, ... }}: {{
deployment.targetEnv = "ec2";
- deployment.ec2.accessKeyId = "logicblox-dev";
+ deployment.ec2.accessKeyId = "lb-nixos";
deployment.ec2.region = "{0}";
deployment.ec2.instanceType = "{2}";
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
- deployment.ec2.securityGroups = [ "admin" ];
+ deployment.ec2.securityGroups = [ "public-ssh" ];
deployment.ec2.ami = "{1}";
}};
}}
@@ -197,29 +185,32 @@ test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]
test_depl.deploy(create_only=True)
test_depl.machines['machine'].run_command("nixos-version")
-if args.hvm:
- image_type = 'hvm'
-else:
- image_type = 'ebs'
-
# Log the AMI ID.
-f = open("{0}.{1}.ami-id".format(args.region, image_type), "w")
-f.write("{0}".format(ami_id))
-f.close()
+f = open("ec2-amis.nix".format(args.region, image_type), "w")
+f.write("{\n")
-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']:
+for dest in [ 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1', 'eu-central-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1']:
+ copy_image = None
if args.region != dest:
- print >> sys.stderr, "copying image from region {0} to {1}".format(args.region, dest)
- conn = boto.ec2.connect_to_region(dest)
- copy_image = conn.copy_image(args.region, ami_id, ami_name, description=None, client_token=None)
+ try:
+ print >> sys.stderr, "copying image from region {0} to {1}".format(args.region, dest)
+ conn = boto.ec2.connect_to_region(dest)
+ copy_image = conn.copy_image(args.region, ami_id, ami_name, description=None, client_token=None)
+ except :
+ print >> sys.stderr, "FAILED!"
# Log the AMI ID.
- f = open("{0}.{1}.ami-id".format(dest, image_type), "w")
- f.write("{0}".format(copy_image.image_id))
- f.close()
+ if copy_image != None:
+ f.write(' "{0}"."{1}".{2} = "{3}";\n'.format(args.channel,dest,"hvm" if args.hvm else "ebs",copy_image.image_id))
+ else:
+ f.write(' "{0}"."{1}".{2} = "{3}";\n'.format(args.channel,args.region,"hvm" if args.hvm else "ebs",ami_id))
+f.write("}\n")
+f.close()
+
if not args.keep:
+ test_depl.logger.set_autoresponse("y")
test_depl.destroy_resources()
test_depl.delete()
diff --git a/nixos/maintainers/scripts/ec2/create-s3-amis.sh b/nixos/maintainers/scripts/ec2/create-s3-amis.sh
index 140b4fcbddb..ed861a3944a 100755
--- a/nixos/maintainers/scripts/ec2/create-s3-amis.sh
+++ b/nixos/maintainers/scripts/ec2/create-s3-amis.sh
@@ -31,17 +31,22 @@ buildAndUploadFor() {
-a "$EC2_ACCESS_KEY" -s "$EC2_SECRET_KEY" --location "$s3location" \
--url http://s3.amazonaws.com
- kernel=$(ec2-describe-images -o amazon --filter "manifest-location=*pv-grub-hd0_1.03-$arch*" --region "$region" | cut -f 2)
+ kernel=$(ec2-describe-images -o amazon --filter "manifest-location=*pv-grub-hd0_1.04-$arch*" --region "$region" | cut -f 2)
echo "using PV-GRUB kernel $kernel"
- ami=$(ec2-register "$bucket/nixos.img.manifest.xml" -n "$name" -d "NixOS $system r$revision" \
+ ami=$(ec2-register "$bucket/nixos.img.manifest.xml" -n "$name" -d "NixOS $system r$revision" -O "$EC2_ACCESS_KEY" -W "$EC2_SECRET_KEY" \
--region "$region" --kernel "$kernel" | cut -f 2)
echo "AMI ID is $ami"
- echo $ami >> $region.s3.ami-id
+ echo " \"14.12\".\"$region\".s3 = \"$ami\";" >> ec2-amis.nix
- ec2-modify-image-attribute --region "$region" "$ami" -l -a all
+ ec2-modify-image-attribute --region "$region" "$ami" -l -a all -O "$EC2_ACCESS_KEY" -W "$EC2_SECRET_KEY"
+
+ for cp_region in us-east-1 us-west-1 us-west-2 eu-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 sa-east-1; do
+ new_ami=$(aws ec2 copy-image --source-image-id $ami --source-region $region --region $cp_region --name "$name" | json ImageId)
+ echo " \"14.12\".\"$cp_region\".s3 = \"$new_ami\";" >> ec2-amis.nix
+ done
done
}
diff --git a/nixos/maintainers/scripts/ec2/ebs-creator.nix b/nixos/maintainers/scripts/ec2/ebs-creator.nix
index 37795d5d5b4..7bb13695fa7 100644
--- a/nixos/maintainers/scripts/ec2/ebs-creator.nix
+++ b/nixos/maintainers/scripts/ec2/ebs-creator.nix
@@ -5,10 +5,9 @@
{ config, pkgs, resources, ... }:
{ deployment.targetEnv = "ec2";
deployment.ec2.instanceType = "c3.large";
- deployment.ec2.securityGroups = [ "admin" ];
+ deployment.ec2.securityGroups = [ "public-ssh" ];
deployment.ec2.ebsBoot = false;
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
- deployment.ec2.zone = "us-east-1e";
environment.systemPackages = [ pkgs.parted ];
};
}
diff --git a/nixos/maintainers/scripts/gce/create-gce.sh b/nixos/maintainers/scripts/gce/create-gce.sh
index 8bf36f33c7d..7f8a0d23027 100755
--- a/nixos/maintainers/scripts/gce/create-gce.sh
+++ b/nixos/maintainers/scripts/gce/create-gce.sh
@@ -1,5 +1,6 @@
#! /bin/sh -e
+BUCKET_NAME=${BUCKET_NAME:-nixos-images}
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)
@@ -8,7 +9,7 @@ nix-build '' \
-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)
+if ! gsutil ls gs://${BUCKET_NAME}/$(basename $img); then
+ gsutil cp $img gs://${BUCKET_NAME}/$(basename $img)
fi
-gcutil addimage $(basename $img .raw.tar.gz | sed 's|\.|-|' | sed 's|_|-|') gs://nixos/$(basename $img)
+gcloud compute images create $(basename $img .raw.tar.gz | sed 's|\.|-|' | sed 's|_|-|') --source-uri gs://${BUCKET_NAME}/$(basename $img)
diff --git a/nixos/modules/config/fonts/fontconfig-ultimate.nix b/nixos/modules/config/fonts/fontconfig-ultimate.nix
new file mode 100644
index 00000000000..02568f9de51
--- /dev/null
+++ b/nixos/modules/config/fonts/fontconfig-ultimate.nix
@@ -0,0 +1,193 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let fcBool = x: if x then "true " else "false ";
+in
+{
+
+ options = {
+
+ fonts = {
+
+ fontconfig = {
+
+ ultimate = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Enable fontconfig-ultimate settings (formerly known as
+ Infinality). Besides the customizable settings in this NixOS
+ module, fontconfig-ultimate also provides many font-specific
+ rendering tweaks.
+ '';
+ };
+
+ allowBitmaps = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Allow bitmap fonts. Set to false to ban all
+ bitmap fonts.
+ '';
+ };
+
+ allowType1 = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Allow Type-1 fonts. Default is false because of
+ poor rendering.
+ '';
+ };
+
+ useEmbeddedBitmaps = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''Use embedded bitmaps in fonts like Calibri.'';
+ };
+
+ forceAutohint = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Force use of the TrueType Autohinter. Useful for debugging or
+ free-software purists.
+ '';
+ };
+
+ renderMonoTTFAsBitmap = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''Render some monospace TTF fonts as bitmaps.'';
+ };
+
+ substitutions = mkOption {
+ type = types.str // {
+ check = flip elem ["none" "free" "combi" "ms"];
+ };
+ default = "free";
+ description = ''
+ Font substitutions to replace common Type 1 fonts with nicer
+ TrueType fonts. free uses free fonts,
+ ms uses Microsoft fonts,
+ combi uses a combination, and
+ none disables the substitutions.
+ '';
+ };
+
+ rendering = mkOption {
+ type = types.attrs;
+ default = pkgs.fontconfig-ultimate.rendering.ultimate;
+ description = ''
+ FreeType rendering settings presets. The default is
+ pkgs.fontconfig-ultimate.rendering.ultimate .
+ The other available styles are:
+ ultimate-lighter ,
+ ultimate-darker ,
+ ultimate-lightest ,
+ ultimate-darkest ,
+ default (the original Infinality default),
+ osx ,
+ ipad ,
+ ubuntu ,
+ linux ,
+ winxplight ,
+ win7light ,
+ winxp ,
+ win7 ,
+ vanilla ,
+ classic ,
+ nudge ,
+ push ,
+ shove ,
+ sharpened ,
+ infinality . Any of the presets may be
+ customized by editing the attributes. To disable, set this option
+ to the empty attribute set {} .
+ '';
+ };
+ };
+ };
+ };
+
+ };
+
+
+ config =
+ let ultimate = config.fonts.fontconfig.ultimate;
+ fontconfigUltimateConf = ''
+
+
+
+
+ ${optionalString (!ultimate.allowBitmaps) ''
+
+
+
+
+ false
+
+
+
+ ''}
+
+ ${optionalString ultimate.allowType1 ''
+
+
+
+
+
+ Type 1
+
+
+
+
+ ''}
+
+
+
+
+ ${fcBool ultimate.useEmbeddedBitmaps}
+
+
+
+
+
+
+ ${fcBool ultimate.forceAutohint}
+
+
+
+
+
+
+ ${fcBool ultimate.renderMonoTTFAsBitmap}
+
+
+
+ ${optionalString (ultimate.substitutions != "none") ''
+
+ ${pkgs.fontconfig-ultimate.confd}/etc/fonts/presets/${ultimate.substitutions}
+ ''}
+
+ ${pkgs.fontconfig-ultimate.confd}/etc/fonts/conf.d
+
+
+ '';
+ in mkIf (config.fonts.fontconfig.enable && ultimate.enable) {
+
+ environment.etc."fonts/conf.d/52-fontconfig-ultimate.conf" = {
+ text = fontconfigUltimateConf;
+ };
+
+ environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/52-fontconfig-ultimate.conf" = {
+ text = fontconfigUltimateConf;
+ };
+
+ environment.variables = ultimate.rendering;
+
+ };
+
+}
diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
index cf70ca264d6..6f17bd396a0 100644
--- a/nixos/modules/config/fonts/fontconfig.nix
+++ b/nixos/modules/config/fonts/fontconfig.nix
@@ -8,52 +8,250 @@ with lib;
fonts = {
- enableFontConfig = mkOption { # !!! should be enableFontconfig
- type = types.bool;
- default = true;
- description = ''
- If enabled, a Fontconfig configuration file will be built
- pointing to a set of default fonts. If you don't care about
- running X11 applications or any other program that uses
- Fontconfig, you can turn this option off and prevent a
- dependency on all those fonts.
- '';
+ fontconfig = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ If enabled, a Fontconfig configuration file will be built
+ pointing to a set of default fonts. If you don't care about
+ running X11 applications or any other program that uses
+ Fontconfig, you can turn this option off and prevent a
+ dependency on all those fonts.
+ '';
+ };
+
+ antialias = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Enable font antialiasing.";
+ };
+
+ dpi = mkOption {
+ type = types.int;
+ default = 0;
+ description = ''
+ Force DPI setting. Setting to 0 disables DPI
+ forcing; the DPI detected for the display will be used.
+ '';
+ };
+
+ defaultFonts = {
+ monospace = mkOption {
+ type = types.listOf types.str;
+ default = ["DejaVu Sans Mono"];
+ description = ''
+ System-wide default monospace font(s). Multiple fonts may be
+ listed in case multiple languages must be supported.
+ '';
+ };
+
+ sansSerif = mkOption {
+ type = types.listOf types.str;
+ default = ["DejaVu Sans"];
+ description = ''
+ System-wide default sans serif font(s). Multiple fonts may be
+ listed in case multiple languages must be supported.
+ '';
+ };
+
+ serif = mkOption {
+ type = types.listOf types.str;
+ default = ["DejaVu Serif"];
+ description = ''
+ System-wide default serif font(s). Multiple fonts may be listed
+ in case multiple languages must be supported.
+ '';
+ };
+ };
+
+ hinting = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Enable TrueType hinting.";
+ };
+
+ autohint = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Enable the autohinter, which provides hinting for otherwise
+ un-hinted fonts. The results are usually lower quality than
+ correctly-hinted fonts.
+ '';
+ };
+
+ style = mkOption {
+ type = types.str // {
+ check = flip elem ["none" "slight" "medium" "full"];
+ };
+ default = "full";
+ description = ''
+ TrueType hinting style, one of none ,
+ slight , medium , or
+ full .
+ '';
+ };
+ };
+
+ includeUserConf = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Include the user configuration from
+ ~/.config/fontconfig/fonts.conf or
+ ~/.config/fontconfig/conf.d .
+ '';
+ };
+
+ subpixel = {
+
+ rgba = mkOption {
+ type = types.string // {
+ check = flip elem ["rgb" "bgr" "vrgb" "vbgr" "none"];
+ };
+ default = "rgb";
+ description = ''
+ Subpixel order, one of none ,
+ rgb , bgr ,
+ vrgb , or vbgr .
+ '';
+ };
+
+ lcdfilter = mkOption {
+ type = types.str // {
+ check = flip elem ["none" "default" "light" "legacy"];
+ };
+ default = "default";
+ description = ''
+ FreeType LCD filter, one of none ,
+ default , light , or
+ legacy .
+ '';
+ };
+
+ };
+
};
};
};
+ config =
+ let fontconfig = config.fonts.fontconfig;
+ fcBool = x: "" + (if x then "true" else "false") + " ";
+ nixosConf = ''
+
+
+
- config = mkIf config.fonts.enableFontConfig {
+
+
+
+ ${fcBool fontconfig.hinting.enable}
+
+
+ ${fcBool fontconfig.hinting.autohint}
+
+
+ hint${fontconfig.hinting.style}
+
+
+ ${fcBool fontconfig.antialias}
+
+
+ ${fontconfig.subpixel.rgba}
+
+
+ lcd${fontconfig.subpixel.lcdfilter}
+
+
- # Bring in the default (upstream) fontconfig configuration.
- environment.etc."fonts/fonts.conf".source =
- pkgs.makeFontsConf { fontDirectories = config.fonts.fonts; };
+
+ ${optionalString (fontconfig.defaultFonts.sansSerif != []) ''
+
+ sans-serif
+
+ ${concatStringsSep "\n"
+ (map (font: "${font} ")
+ fontconfig.defaultFonts.sansSerif)}
+
+
+ ''}
+ ${optionalString (fontconfig.defaultFonts.serif != []) ''
+
+ serif
+
+ ${concatStringsSep "\n"
+ (map (font: "${font} ")
+ fontconfig.defaultFonts.serif)}
+
+
+ ''}
+ ${optionalString (fontconfig.defaultFonts.monospace != []) ''
+
+ monospace
+
+ ${concatStringsSep "\n"
+ (map (font: "${font} ")
+ fontconfig.defaultFonts.monospace)}
+
+
+ ''}
- environment.etc."fonts/conf.d/00-nixos.conf".text =
- ''
-
-
-
+ ${optionalString (fontconfig.dpi != 0) ''
+
+
+ ${toString fontconfig.dpi}
+
+
+ ''}
-
-
-
- hintslight
-
-
+
+ '';
+ in mkIf fontconfig.enable {
-
- '';
+ # Fontconfig 2.10 backward compatibility
- # FIXME: This variable is no longer needed, but we'll keep it
- # around for a while for applications linked against old
- # fontconfig builds.
- environment.variables.FONTCONFIG_FILE = "/etc/fonts/fonts.conf";
+ # Bring in the default (upstream) fontconfig configuration, only for fontconfig 2.10
+ environment.etc."fonts/fonts.conf".source =
+ pkgs.makeFontsConf { fontconfig = pkgs.fontconfig_210; fontDirectories = config.fonts.fonts; };
- environment.systemPackages = [ pkgs.fontconfig ];
+ environment.etc."fonts/conf.d/98-nixos.conf".text = nixosConf;
- };
+ # Versioned fontconfig > 2.10. Take shared fonts.conf from fontconfig.
+ # Otherwise specify only font directories.
+ environment.etc."fonts/${pkgs.fontconfig.configVersion}/fonts.conf".source =
+ "${pkgs.fontconfig}/etc/fonts/fonts.conf";
+
+ environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/00-nixos.conf".text =
+ ''
+
+
+
+
+ ${concatStringsSep "\n" (map (font: "${font} ") config.fonts.fonts)}
+
+ '';
+
+ environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/98-nixos.conf".text = nixosConf;
+
+ environment.etc."fonts/${pkgs.fontconfig.configVersion}/conf.d/99-user.conf" = {
+ enable = fontconfig.includeUserConf;
+ text = ''
+
+
+
+ fontconfig/conf.d
+ fontconfig/fonts.conf
+
+ '';
+ };
+
+ environment.systemPackages = [ pkgs.fontconfig ];
+
+ };
}
diff --git a/nixos/modules/config/fonts/fonts.nix b/nixos/modules/config/fonts/fonts.nix
index f6060a910a1..a3fa4bd9778 100644
--- a/nixos/modules/config/fonts/fonts.nix
+++ b/nixos/modules/config/fonts/fonts.nix
@@ -13,14 +13,6 @@ with lib;
type = types.listOf types.path;
example = literalExample "[ pkgs.dejavu_fonts ]";
description = "List of primary font paths.";
- apply = list: list ++
- [ # - the user's current profile
- "~/.nix-profile/lib/X11/fonts"
- "~/.nix-profile/share/fonts"
- # - the default profile
- "/nix/var/nix/profiles/default/lib/X11/fonts"
- "/nix/var/nix/profiles/default/share/fonts"
- ];
};
};
@@ -33,7 +25,7 @@ with lib;
[ pkgs.xorg.fontbhttf
pkgs.xorg.fontbhlucidatypewriter100dpi
pkgs.xorg.fontbhlucidatypewriter75dpi
- pkgs.ttf_bitstream_vera
+ pkgs.dejavu_fonts
pkgs.freefont_ttf
pkgs.liberation_ttf
pkgs.xorg.fontbh100dpi
diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix
index 136a5bda745..f99cea7d17b 100644
--- a/nixos/modules/config/networking.nix
+++ b/nixos/modules/config/networking.nix
@@ -39,6 +39,73 @@ in
'';
};
+ networking.proxy = {
+
+ default = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy.
+ '';
+ example = "http://127.0.0.1:3128";
+ };
+
+ httpProxy = lib.mkOption {
+ type = types.nullOr types.str;
+ default = cfg.proxy.default;
+ description = ''
+ This option specifies the http_proxy environment variable.
+ '';
+ example = "http://127.0.0.1:3128";
+ };
+
+ httpsProxy = lib.mkOption {
+ type = types.nullOr types.str;
+ default = cfg.proxy.default;
+ description = ''
+ This option specifies the https_proxy environment variable.
+ '';
+ example = "http://127.0.0.1:3128";
+ };
+
+ ftpProxy = lib.mkOption {
+ type = types.nullOr types.str;
+ default = cfg.proxy.default;
+ description = ''
+ This option specifies the ftp_proxy environment variable.
+ '';
+ example = "http://127.0.0.1:3128";
+ };
+
+ rsyncProxy = lib.mkOption {
+ type = types.nullOr types.str;
+ default = cfg.proxy.default;
+ description = ''
+ This option specifies the rsync_proxy environment variable.
+ '';
+ example = "http://127.0.0.1:3128";
+ };
+
+ noProxy = lib.mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ This option specifies the no_proxy environment variable.
+ If a default proxy is used and noProxy is null,
+ then noProxy will be set to 127.0.0.1,localhost.
+ '';
+ example = "127.0.0.1,localhost,.localdomain";
+ };
+
+ envVars = lib.mkOption {
+ type = types.attrs;
+ internal = true;
+ default = {};
+ description = ''
+ Environment variables used for the network proxy.
+ '';
+ };
+ };
};
config = {
@@ -73,7 +140,7 @@ in
'' + optionalString config.services.nscd.enable ''
# Invalidate the nscd cache whenever resolv.conf is
# regenerated.
- libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service'
+ libc_restart='${pkgs.systemd}/bin/systemctl try-restart --no-block nscd.service 2> /dev/null'
'' + optionalString cfg.dnsSingleRequest ''
# only send one DNS request at a time
resolv_conf_options='single-request'
@@ -84,13 +151,59 @@ in
dnsmasq_conf=/etc/dnsmasq-conf.conf
dnsmasq_resolv=/etc/dnsmasq-resolv.conf
'';
- };
+
+ } // (optionalAttrs config.services.resolved.enable (
+ if dnsmasqResolve then {
+ "dnsmasq-resolv.conf".source = "/run/systemd/resolve/resolv.conf";
+ } else {
+ "resolv.conf".source = "/run/systemd/resolve/resolv.conf";
+ }
+ ));
+
+ networking.proxy.envVars =
+ optionalAttrs (cfg.proxy.default != null) {
+ # other options already fallback to proxy.default
+ no_proxy = "127.0.0.1,localhost";
+ } // optionalAttrs (cfg.proxy.httpProxy != null) {
+ http_proxy = cfg.proxy.httpProxy;
+ } // optionalAttrs (cfg.proxy.httpsProxy != null) {
+ https_proxy = cfg.proxy.httpsProxy;
+ } // optionalAttrs (cfg.proxy.rsyncProxy != null) {
+ rsync_proxy = cfg.proxy.rsyncProxy;
+ } // optionalAttrs (cfg.proxy.ftpProxy != null) {
+ ftp_proxy = cfg.proxy.ftpProxy;
+ } // optionalAttrs (cfg.proxy.noProxy != null) {
+ no_proxy = cfg.proxy.noProxy;
+ };
+
+ # Install the proxy environment variables
+ environment.sessionVariables = cfg.proxy.envVars;
# The ‘ip-up’ target is started when we have IP connectivity. So
# services that depend on IP connectivity (like ntpd) should be
# pulled in by this target.
systemd.targets.ip-up.description = "Services Requiring IP Connectivity";
+ # This is needed when /etc/resolv.conf is being overriden by networkd
+ # and other configurations. If the file is destroyed by an environment
+ # activation then it must be rebuilt so that applications which interface
+ # with /etc/resolv.conf directly don't break.
+ system.activationScripts.resolvconf = stringAfter [ "etc" "tmpfs" "var" ]
+ ''
+ # Systemd resolved controls its own resolv.conf
+ rm -f /run/resolvconf/interfaces/systemd
+ ${optionalString config.services.resolved.enable ''
+ rm -rf /run/resolvconf/interfaces
+ mkdir -p /run/resolvconf/interfaces
+ ln -s /run/systemd/resolve/resolv.conf /run/resolvconf/interfaces/systemd
+ ''}
+
+ # Make sure resolv.conf is up to date if not managed by systemd
+ ${optionalString (!config.services.resolved.enable) ''
+ ${pkgs.openresolv}/bin/resolvconf -u
+ ''}
+ '';
+
};
-}
+ }
diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix
index f91dbb4cc28..13477337bda 100644
--- a/nixos/modules/config/no-x-libs.nix
+++ b/nixos/modules/config/no-x-libs.nix
@@ -24,9 +24,9 @@ with lib;
programs.ssh.setXAuthLocation = false;
security.pam.services.su.forwardXAuth = lib.mkForce false;
- fonts.enableFontConfig = false;
+ fonts.fontconfig.enable = false;
nixpkgs.config.packageOverrides = pkgs:
- { dbus = pkgs.dbus.override { useX11 = false; }; };
+ { dbus = pkgs.dbus.override { x11Support = false; }; };
};
}
diff --git a/nixos/modules/config/nsswitch.nix b/nixos/modules/config/nsswitch.nix
index 45695d9cb89..a39c2895bf8 100644
--- a/nixos/modules/config/nsswitch.nix
+++ b/nixos/modules/config/nsswitch.nix
@@ -8,6 +8,7 @@ let
inherit (config.services.avahi) nssmdns;
inherit (config.services.samba) nsswins;
+ ldap = config.users.ldap.enable;
in
@@ -35,29 +36,27 @@ in
config = {
- environment.etc =
- [ # Name Service Switch configuration file. Required by the C library.
- # !!! Factor out the mdns stuff. The avahi module should define
- # an option used by this module.
- { source = pkgs.writeText "nsswitch.conf"
- ''
- passwd: files ldap
- group: files ldap
- shadow: files ldap
- hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} ${optionalString nsswins "wins"} myhostname
- networks: files dns
- ethers: files
- services: files
- protocols: files
- '';
- target = "nsswitch.conf";
- }
- ];
+ # Name Service Switch configuration file. Required by the C
+ # library. !!! Factor out the mdns stuff. The avahi module
+ # should define an option used by this module.
+ environment.etc."nsswitch.conf".text =
+ ''
+ passwd: files ${optionalString ldap "ldap"}
+ group: files ${optionalString ldap "ldap"}
+ shadow: files ${optionalString ldap "ldap"}
+ hosts: files ${optionalString nssmdns "mdns_minimal [NOTFOUND=return]"} dns ${optionalString nssmdns "mdns"} ${optionalString nsswins "wins"} myhostname mymachines
+ networks: files dns
+ ethers: files
+ services: files
+ protocols: files
+ '';
- # Use nss-myhostname to ensure that our hostname always resolves to
- # a valid IP address. It returns all locally configured IP
- # addresses, or ::1 and 127.0.0.2 as fallbacks.
- system.nssModules = [ pkgs.systemd ];
+ # Systemd provides nss-myhostname to ensure that our hostname
+ # always resolves to a valid IP address. It returns all locally
+ # configured IP addresses, or ::1 and 127.0.0.2 as
+ # fallbacks. Systemd also provides nss-mymachines to return IP
+ # addresses of local containers.
+ system.nssModules = [ config.systemd.package ];
};
}
diff --git a/nixos/modules/config/pulseaudio.nix b/nixos/modules/config/pulseaudio.nix
index 1b84bbaf10c..c41e4ea604d 100644
--- a/nixos/modules/config/pulseaudio.nix
+++ b/nixos/modules/config/pulseaudio.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, pkgs_i686, ... }:
with pkgs;
with lib;
@@ -10,10 +10,16 @@ let
systemWide = cfg.enable && cfg.systemWide;
nonSystemWide = cfg.enable && !cfg.systemWide;
- uid = config.ids.uids.pulseaudio;
- gid = config.ids.gids.pulseaudio;
+ # Forces 32bit pulseaudio and alsaPlugins to be built/supported for apps
+ # using 32bit alsa on 64bit linux.
+ enable32BitAlsaPlugins = stdenv.isx86_64 && (pkgs_i686.alsaLib != null && pkgs_i686.pulseaudio != null);
- stateDir = "/run/pulse";
+ ids = config.ids;
+
+ uid = ids.uids.pulseaudio;
+ gid = ids.gids.pulseaudio;
+
+ stateDir = "/var/run/pulse";
# Create pulse/client.conf even if PulseAudio is disabled so
# that we can disable the autospawn feature in programs that
@@ -26,21 +32,25 @@ let
# Write an /etc/asound.conf that causes all ALSA applications to
# be re-routed to the PulseAudio server through ALSA's Pulse
# plugin.
- alsaConf = writeText "asound.conf" ''
+ alsaConf = writeText "asound.conf" (''
pcm_type.pulse {
- lib ${alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so
+ libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;
+ ${lib.optionalString enable32BitAlsaPlugins
+ "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so ;"}
}
pcm.!default {
type pulse
hint.description "Default Audio Device (via PulseAudio)"
}
ctl_type.pulse {
- lib ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so
+ libs.native = ${alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;
+ ${lib.optionalString enable32BitAlsaPlugins
+ "libs.32Bit = ${pkgs_i686.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so ;"}
}
ctl.!default {
type pulse
}
- '';
+ '');
in {
@@ -69,8 +79,7 @@ in {
};
configFile = mkOption {
- type = types.uniq types.path;
- default = "${cfg.package}/etc/pulse/default.pa";
+ type = types.path;
description = ''
The path to the configuration the PulseAudio server
should use. By default, the "default.pa" configuration
@@ -110,6 +119,8 @@ in {
target = "pulse/client.conf";
source = clientConf;
};
+
+ hardware.pulseaudio.configFile = mkDefault "${cfg.package}/etc/pulse/default.pa";
}
(mkIf cfg.enable {
@@ -138,6 +149,8 @@ in {
group = "pulse";
extraGroups = [ "audio" ];
description = "PulseAudio system service user";
+ home = stateDir;
+ createHome = true;
};
users.extraGroups.pulse.gid = gid;
@@ -147,10 +160,6 @@ in {
wantedBy = [ "sound.target" ];
before = [ "sound.target" ];
environment.PULSE_RUNTIME_PATH = stateDir;
- preStart = ''
- mkdir -p --mode 755 ${stateDir}
- chown -R pulse:pulse ${stateDir}
- '';
serviceConfig = {
ExecStart = "${cfg.package}/bin/pulseaudio -D --log-level=${cfg.daemon.logLevel} --system --use-pid-file -n --file=${cfg.configFile}";
PIDFile = "${stateDir}/pid";
diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix
index 2559c53ac16..e5b342afcc4 100644
--- a/nixos/modules/config/shells-environment.nix
+++ b/nixos/modules/config/shells-environment.nix
@@ -9,6 +9,23 @@ let
cfg = config.environment;
+ exportedEnvVars =
+ let
+ absoluteVariables =
+ mapAttrs (n: toList) cfg.variables;
+
+ suffixedVariables =
+ flip mapAttrs cfg.profileRelativeEnvVars (envVar: listSuffixes:
+ concatMap (profile: map (suffix: "${profile}${suffix}") listSuffixes) cfg.profiles
+ );
+
+ allVariables =
+ zipAttrsWith (n: concatLists) [ absoluteVariables suffixedVariables ];
+
+ exportVariables =
+ mapAttrsToList (n: v: ''export ${n}="${concatStringsSep ":" v}"'') allVariables;
+ in
+ concatStringsSep "\n" exportVariables;
in
{
@@ -49,22 +66,15 @@ in
type = types.listOf types.string;
};
- environment.profileVariables = mkOption {
- default = (p: {});
+ environment.profileRelativeEnvVars = mkOption {
+ type = types.attrsOf (types.listOf types.str);
+ example = { PATH = [ "/bin" "/sbin" ]; MANPATH = [ "/man" "/share/man" ]; };
description = ''
- A function which given a profile path should give back
- a set of environment variables for that profile.
+ Attribute set of environment variable. Each attribute maps to a list
+ of relative paths. Each relative path is appended to the each profile
+ of environment.profiles to form the content of the
+ corresponding environment variable.
'';
- # !!! this should be of the following type:
- #type = types.functionTo (types.attrsOf (types.optionSet envVar));
- # and envVar should be changed to something more like environOpts.
- # Having unique `value' _or_ multiple `list' is much more useful
- # than just sticking everything together with ':' unconditionally.
- # Anyway, to have this type mentioned above
- # types.optionSet needs to be transformed into a type constructor
- # (it has a !!! mark on that in nixpkgs)
- # for now we hack all this to be
- type = types.functionTo (types.attrsOf (types.listOf types.string));
};
# !!! isn't there a better way?
@@ -165,10 +175,7 @@ in
system.build.setEnvironment = pkgs.writeText "set-environment"
''
- ${concatStringsSep "\n" (
- (mapAttrsToList (n: v: ''export ${n}="${concatStringsSep ":" v}"'')
- # This line is a kind of a hack because of !!! note above
- (zipAttrsWith (const concatLists) ([ (mapAttrs (n: v: [ v ]) cfg.variables) ] ++ map cfg.profileVariables cfg.profiles))))}
+ ${exportedEnvVars}
${cfg.extraInit}
diff --git a/nixos/modules/config/sysctl.nix b/nixos/modules/config/sysctl.nix
index 3b6ccd380c7..e83562a8356 100644
--- a/nixos/modules/config/sysctl.nix
+++ b/nixos/modules/config/sysctl.nix
@@ -64,6 +64,6 @@ in
#
# Removed under grsecurity.
boot.kernel.sysctl."kernel.kptr_restrict" =
- if config.security.grsecurity.enable then null else 1;
+ if (config.boot.kernelPackages.kernel.features.grsecurity or false) then null else 1;
};
}
diff --git a/nixos/modules/config/timezone.nix b/nixos/modules/config/timezone.nix
index c8592284077..06857139311 100644
--- a/nixos/modules/config/timezone.nix
+++ b/nixos/modules/config/timezone.nix
@@ -14,10 +14,14 @@ in
time = {
timeZone = mkOption {
- default = "CET";
+ default = "UTC";
type = types.str;
example = "America/New_York";
- description = "The time zone used when displaying times and dates.";
+ description = ''
+ The time zone used when displaying times and dates. See
+ for a comprehensive list of possible values for this setting.
+ '';
};
hardwareClockInLocalTime = mkOption {
diff --git a/nixos/modules/config/update-users-groups.pl b/nixos/modules/config/update-users-groups.pl
index 197b65e27c4..de73de91629 100644
--- a/nixos/modules/config/update-users-groups.pl
+++ b/nixos/modules/config/update-users-groups.pl
@@ -6,6 +6,15 @@ use JSON;
make_path("/var/lib/nixos", { mode => 0755 });
+sub hashPassword {
+ my ($password) = @_;
+ my $salt = "";
+ my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z');
+ $salt .= $chars[rand 64] for (1..8);
+ return crypt($password, '$6$' . $salt . '$');
+}
+
+
# Functions for allocating free GIDs/UIDs. FIXME: respect ID ranges in
# /etc/login.defs.
sub allocId {
@@ -114,7 +123,7 @@ foreach my $g (@{$spec->{groups}}) {
}
# Update the persistent list of declarative groups.
-write_file($declGroupsFile, join(" ", sort(keys %groupsOut)));
+write_file($declGroupsFile, { binmode => ':utf8' }, join(" ", sort(keys %groupsOut)));
# Merge in the existing /etc/group.
foreach my $name (keys %groupsCur) {
@@ -131,7 +140,7 @@ foreach my $name (keys %groupsCur) {
# 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);
+write_file("/etc/group.tmp", { binmode => ':utf8' }, @lines);
rename("/etc/group.tmp", "/etc/group") or die;
system("nscd --invalidate group");
@@ -160,13 +169,19 @@ foreach my $u (@{$spec->{users}}) {
} 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->{initialPassword}) {
+ $u->{hashedPassword} = hashPassword($u->{initialPassword});
+ } elsif (defined $u->{initialHashedPassword}) {
+ $u->{hashedPassword} = $u->{initialHashedPassword};
}
}
+ # Create a home directory.
+ if ($u->{createHome} && ! -e $u->{home}) {
+ 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});
@@ -174,6 +189,8 @@ foreach my $u (@{$spec->{users}}) {
} else {
warn "warning: password file ‘$u->{passwordFile}’ does not exist\n";
}
+ } elsif (defined $u->{password}) {
+ $u->{hashedPassword} = hashPassword($u->{password});
}
$u->{fakePassword} = $existing->{fakePassword} // "x";
@@ -181,7 +198,7 @@ foreach my $u (@{$spec->{users}}) {
}
# Update the persistent list of declarative users.
-write_file($declUsersFile, join(" ", sort(keys %usersOut)));
+write_file($declUsersFile, { binmode => ':utf8' }, join(" ", sort(keys %usersOut)));
# Merge in the existing /etc/passwd.
foreach my $name (keys %usersCur) {
@@ -197,7 +214,7 @@ foreach my $name (keys %usersCur) {
# 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);
+write_file("/etc/passwd.tmp", { binmode => ':utf8' }, @lines);
rename("/etc/passwd.tmp", "/etc/passwd") or die;
system("nscd --invalidate passwd");
@@ -208,32 +225,22 @@ my %shadowSeen;
foreach my $line (-f "/etc/shadow" ? read_file("/etc/shadow") : ()) {
chomp $line;
- my ($name, $password, @rest) = split(':', $line, -9);
+ my ($name, $hashedPassword, @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";
+ $hashedPassword = "!" if !$spec->{mutableUsers};
+ $hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword} && !$spec->{mutableUsers}; # FIXME
+ push @shadowNew, join(":", $name, $hashedPassword, @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};
+ my $hashedPassword = "!";
+ $hashedPassword = $u->{hashedPassword} if defined $u->{hashedPassword};
# FIXME: set correct value for sp_lstchg.
- push @shadowNew, join(":", $u->{name}, $password, "1::::::") . "\n";
+ push @shadowNew, join(":", $u->{name}, $hashedPassword, "1::::::") . "\n";
}
-write_file("/etc/shadow.tmp", { perms => 0600 }, @shadowNew);
+write_file("/etc/shadow.tmp", { binmode => ':utf8', 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";
- }
-}
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index d172ddb6bca..9d48edf2f26 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -8,23 +8,28 @@ let
cfg = config.users;
passwordDescription = ''
- The options hashedPassword ,
- password and passwordFile
+ The options hashedPassword ,
+ password and passwordFile
controls what password is set for the user.
- hashedPassword overrides both
- password and passwordFile .
- password overrides passwordFile .
+ hashedPassword overrides both
+ password and passwordFile .
+ password overrides passwordFile .
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 users.mutableUsers is true, the
+ If the option users.mutableUsers 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
- users.mutableUsers is false, you cannot change
+ users.mutableUsers is false, you cannot change
user passwords, they will always be set according to the password
options.
'';
+ hashedPasswordDescription = ''
+ To generate hashed password install mkpassword
+ package and run mkpasswd -m sha-512 .
+ '';
+
userOpts = { name, config, ... }: {
options = {
@@ -105,7 +110,7 @@ let
shell = mkOption {
type = types.str;
- default = "/run/current-system/sw/sbin/nologin";
+ default = "/run/current-system/sw/bin/nologin";
description = "The path to the user's shell.";
};
@@ -155,7 +160,7 @@ let
default = false;
description = ''
If true, the user's shell will be set to
- cfg.defaultUserShell .
+ users.defaultUserShell .
'';
};
@@ -163,8 +168,9 @@ let
type = with types; uniq (nullOr str);
default = null;
description = ''
- Specifies the (hashed) password for the user.
+ Specifies the hashed password for the user.
${passwordDescription}
+ ${hashedPasswordDescription}
'';
};
@@ -184,13 +190,46 @@ let
type = with types; uniq (nullOr string);
default = null;
description = ''
- The path to a file that contains the user's password. The password
+ The full path to a file that contains the user's password. The password
file is read on each system activation. The file should contain
exactly one line, which should be the password in an encrypted form
that is suitable for the chpasswd -e command.
${passwordDescription}
'';
};
+
+ initialHashedPassword = mkOption {
+ type = with types; uniq (nullOr str);
+ default = null;
+ description = ''
+ Specifies the initial hashed password for the user, i.e. the
+ hashed password assigned if the user does not already
+ exist. If users.mutableUsers is true, the
+ password can be changed subsequently using the
+ passwd command. Otherwise, it's
+ equivalent to setting the password option.
+
+ ${hashedPasswordDescription}
+ '';
+ };
+
+ initialPassword = mkOption {
+ type = with types; uniq (nullOr str);
+ default = null;
+ description = ''
+ Specifies the initial password for the user, i.e. the
+ password assigned if the user does not already exist. If
+ users.mutableUsers is true, the password
+ can be changed subsequently using the
+ passwd command. Otherwise, it's
+ equivalent to setting the password
+ option. The same caveat applies: the password specified here
+ is world-readable in the Nix store, so it should only be
+ used for guest accounts or passwords that will be changed
+ promptly.
+ '';
+ };
+
};
config = mkMerge
@@ -204,6 +243,14 @@ let
useDefaultShell = mkDefault true;
isSystemUser = mkDefault false;
})
+ # If !mutableUsers, setting ‘initialPassword’ is equivalent to
+ # setting ‘password’ (and similarly for hashed passwords).
+ (mkIf (!cfg.mutableUsers && config.initialPassword != null) {
+ password = mkDefault config.initialPassword;
+ })
+ (mkIf (!cfg.mutableUsers && config.initialHashedPassword != null) {
+ hashedPassword = mkDefault config.initialHashedPassword;
+ })
];
};
@@ -276,23 +323,17 @@ let
};
};
- filterNull = a: filter (x: hasAttr a x && getAttr a x != null);
-
- sortOn "gid" (filterNull "gid" (attrValues cfg.extraGroups))
- sortOn "uid" (filterNull "uid" (attrValues cfg.extraUsers))
mkSubuidEntry = user: concatStrings (
map (range: "${user.name}:${toString range.startUid}:${toString range.count}\n")
- user.subUidRanges);
+ user.subUidRanges);
- subuidFile = concatStrings (map mkSubuidEntry (
- sortOn "uid" (filterNull "uid" (attrValues cfg.extraUsers))));
+ subuidFile = concatStrings (map mkSubuidEntry (attrValues cfg.extraUsers));
mkSubgidEntry = user: concatStrings (
map (range: "${user.name}:${toString range.startGid}:${toString range.count}\n")
user.subGidRanges);
- subgidFile = concatStrings (map mkSubgidEntry (
- sortOn "uid" (filterNull "uid" (attrValues cfg.extraUsers))));
+ subgidFile = concatStrings (map mkSubgidEntry (attrValues cfg.extraUsers));
idsAreUnique = set: idAttr: !(fold (name: args@{ dup, acc }:
let
@@ -307,18 +348,19 @@ let
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 {
+ spec = pkgs.writeText "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;
+ password passwordFile hashedPassword
+ initialPassword initialHashedPassword;
}) cfg.extraUsers;
groups = mapAttrsToList (n: g:
{ inherit (g) name gid;
- members = mapAttrsToList (n: u: u.name) (
+ members = g.members ++ (mapAttrsToList (n: u: u.name) (
filterAttrs (n: u: elem g.name u.extraGroups) cfg.extraUsers
- );
+ ));
}) cfg.extraGroups;
});
@@ -332,21 +374,24 @@ in {
type = types.bool;
default = true;
description = ''
- If true, you are free to add new users and groups to the system
+ If set to true , you are free to add new users and groups to the system
with the ordinary useradd and
groupadd commands. On system activation, the
existing contents of the /etc/passwd and
/etc/group files will be merged with the
contents generated from the users.extraUsers and
- users.extraGroups options. If
- mutableUsers 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
- users.extraUsers configuration on activation. If
- this option is true, the initial password for a user will be set
+ users.extraGroups options.
+ The initial password for a user will be set
according to users.extraUsers , but existing passwords
will not be changed.
+
+
+ If set to false , the contents of the user and
+ group files will simply be replaced on system activation. This also
+ holds for the user passwords; all changed
+ passwords will be reset according to the
+ users.extraUsers configuration on activation.
+
'';
};
@@ -392,24 +437,12 @@ in {
options = [ groupOpts ];
};
+ # FIXME: obsolete - will remove.
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 su or
- sudo ). The string !
- prevents root from logging in using a password.
- Note that setting this option sets
- users.extraUsers.root.hashedPassword .
- Also, if users.mutableUsers 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.
- '';
+ visible = false;
};
};
@@ -427,7 +460,7 @@ in {
shell = mkDefault cfg.defaultUserShell;
group = "root";
extraGroups = [ "grsecurity" ];
- hashedPassword = mkDefault config.security.initialRootPassword;
+ initialHashedPassword = mkDefault config.security.initialRootPassword;
};
nobody = {
uid = ids.uids.nobody;
@@ -456,6 +489,7 @@ in {
utmp.gid = ids.gids.utmp;
adm.gid = ids.gids.adm;
grsecurity.gid = ids.gids.grsecurity;
+ input.gid = ids.gids.input;
};
system.activationScripts.users = stringAfter [ "etc" ]
diff --git a/nixos/modules/config/vpnc.nix b/nixos/modules/config/vpnc.nix
new file mode 100644
index 00000000000..68d755232eb
--- /dev/null
+++ b/nixos/modules/config/vpnc.nix
@@ -0,0 +1,41 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.networking.vpnc;
+ mkServiceDef = name: value:
+ {
+ name = "vpnc/${name}.conf";
+ value = { text = value; };
+ };
+
+in
+{
+ options = {
+ networking.vpnc = {
+ services = mkOption {
+ type = types.attrsOf types.str;
+ default = {};
+ example = {
+ test =
+ ''
+ IPSec gateway 192.168.1.1
+ IPSec ID someID
+ IPSec secret secretKey
+ Xauth username name
+ Xauth password pass
+ '';
+ };
+ description =
+ ''
+ The names of cisco VPNs and their associated definitions
+ '';
+ };
+ };
+ };
+
+ config.environment.etc = mapAttrs' mkServiceDef cfg.services;
+}
+
+
diff --git a/nixos/modules/hardware/all-firmware.nix b/nixos/modules/hardware/all-firmware.nix
index 3820a95b12e..e4bdeb55cad 100644
--- a/nixos/modules/hardware/all-firmware.nix
+++ b/nixos/modules/hardware/all-firmware.nix
@@ -12,7 +12,7 @@ with lib;
default = false;
type = types.bool;
description = ''
- Turn on this option if you want to enable all the firmware shipped with Debian/Ubuntu.
+ Turn on this option if you want to enable all the firmware shipped in linux-firmware.
'';
};
@@ -22,7 +22,9 @@ with lib;
###### implementation
config = mkIf config.hardware.enableAllFirmware {
- hardware.firmware = [ "${pkgs.firmwareLinuxNonfree}/lib/firmware" ];
+ hardware.firmware = [
+ "${pkgs.firmwareLinuxNonfree}/lib/firmware"
+ ];
};
}
diff --git a/nixos/modules/hardware/cpu/amd-microcode.nix b/nixos/modules/hardware/cpu/amd-microcode.nix
index 86a3df5da21..d44f01a4959 100644
--- a/nixos/modules/hardware/cpu/amd-microcode.nix
+++ b/nixos/modules/hardware/cpu/amd-microcode.nix
@@ -22,8 +22,7 @@ with lib;
###### implementation
config = mkIf config.hardware.cpu.amd.updateMicrocode {
- hardware.firmware = [ "${pkgs.amdUcode}/lib/firmware" ];
- boot.kernelModules = [ "microcode" ];
+ boot.initrd.prepend = [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
};
}
diff --git a/nixos/modules/hardware/cpu/intel-microcode.nix b/nixos/modules/hardware/cpu/intel-microcode.nix
index 800c391b293..89ae4f45806 100644
--- a/nixos/modules/hardware/cpu/intel-microcode.nix
+++ b/nixos/modules/hardware/cpu/intel-microcode.nix
@@ -22,8 +22,7 @@ with lib;
###### implementation
config = mkIf config.hardware.cpu.intel.updateMicrocode {
- hardware.firmware = [ "${pkgs.microcodeIntel}/lib/firmware" ];
- boot.kernelModules = [ "microcode" ];
+ boot.initrd.prepend = [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
};
}
diff --git a/nixos/modules/hardware/ksm.nix b/nixos/modules/hardware/ksm.nix
new file mode 100644
index 00000000000..d6ac69b5d65
--- /dev/null
+++ b/nixos/modules/hardware/ksm.nix
@@ -0,0 +1,18 @@
+{ config, lib, ... }:
+
+{
+ options.hardware.enableKSM = lib.mkEnableOption "Kernel Same-Page Merging";
+
+ config = lib.mkIf config.hardware.enableKSM {
+ systemd.services.enable-ksm = {
+ description = "Enable Kernel Same-Page Merging";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "systemd-udev-settle.service" ];
+ script = ''
+ if [ -e /sys/kernel/mm/ksm ]; then
+ echo 1 > /sys/kernel/mm/ksm/run
+ fi
+ '';
+ };
+ };
+}
diff --git a/nixos/modules/hardware/opengl.nix b/nixos/modules/hardware/opengl.nix
index f894c830eb6..7693bd5bb45 100644
--- a/nixos/modules/hardware/opengl.nix
+++ b/nixos/modules/hardware/opengl.nix
@@ -16,7 +16,6 @@ let
[ p.mesa_drivers
p.mesa_noglu # mainly for libGL
(if cfg.s3tcSupport then p.libtxc_dxtn else p.libtxc_dxtn_s2tc)
- p.udev
];
};
@@ -46,7 +45,8 @@ in
description = ''
On 64-bit systems, whether to support Direct Rendering for
32-bit applications (such as Wine). This is currently only
- supported for the nvidia driver and for
+ supported for the nvidia and
+ ati_unfree drivers, as well as
Mesa .
'';
};
@@ -104,22 +104,9 @@ in
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.package = mkDefault (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";
- };
+ boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
};
}
diff --git a/nixos/modules/hardware/video/ati.nix b/nixos/modules/hardware/video/ati.nix
new file mode 100644
index 00000000000..033e49d2233
--- /dev/null
+++ b/nixos/modules/hardware/video/ati.nix
@@ -0,0 +1,37 @@
+# This module provides the proprietary ATI X11 / OpenGL drivers.
+
+{ config, lib, pkgs, pkgs_i686, ... }:
+
+with lib;
+
+let
+
+ drivers = config.services.xserver.videoDrivers;
+
+ enabled = elem "ati_unfree" drivers;
+
+ ati_x11 = config.boot.kernelPackages.ati_drivers_x11;
+
+in
+
+{
+
+ config = mkIf enabled {
+
+ services.xserver.drivers = singleton
+ { name = "fglrx"; modules = [ ati_x11 ]; libPath = [ "${ati_x11}/lib" ]; };
+
+ hardware.opengl.package = ati_x11;
+ hardware.opengl.package32 = pkgs_i686.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; };
+
+ environment.systemPackages = [ ati_x11 ];
+
+ boot.extraModulePackages = [ ati_x11 ];
+
+ boot.blacklistedKernelModules = [ "radeon" ];
+
+ environment.etc."ati".source = "${ati_x11}/etc/ati";
+
+ };
+
+}
diff --git a/nixos/modules/hardware/video/bumblebee.nix b/nixos/modules/hardware/video/bumblebee.nix
index 52dea798f87..e20ebc3041e 100644
--- a/nixos/modules/hardware/video/bumblebee.nix
+++ b/nixos/modules/hardware/video/bumblebee.nix
@@ -1,7 +1,13 @@
{ config, lib, pkgs, ... }:
-let kernel = config.boot.kernelPackages; in
with lib;
+let
+ kernel = config.boot.kernelPackages;
+ bumblebee = if config.hardware.bumblebee.connectDisplay
+ then pkgs.bumblebee_display
+ else pkgs.bumblebee;
+
+in
{
@@ -23,6 +29,17 @@ with lib;
type = types.uniq types.str;
description = ''Group for bumblebee socket'';
};
+ hardware.bumblebee.connectDisplay = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Set to true if you intend to connect your discrete card to a
+ monitor. This option will set up your Nvidia card for EDID
+ discovery and to turn on the monitor signal.
+
+ Only nvidia driver is supported so far.
+ '';
+ };
};
config = mkIf config.hardware.bumblebee.enable {
@@ -30,13 +47,13 @@ with lib;
boot.kernelModules = [ "bbswitch" ];
boot.extraModulePackages = [ kernel.bbswitch kernel.nvidia_x11 ];
- environment.systemPackages = [ pkgs.bumblebee ];
+ environment.systemPackages = [ bumblebee pkgs.primus ];
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 ];
+ path = [ kernel.bbswitch bumblebee ];
serviceConfig = {
Restart = "always";
RestartSec = 60;
diff --git a/nixos/modules/hardware/video/nvidia.nix b/nixos/modules/hardware/video/nvidia.nix
index 2b9221ec5d7..711576982ec 100644
--- a/nixos/modules/hardware/video/nvidia.nix
+++ b/nixos/modules/hardware/video/nvidia.nix
@@ -11,17 +11,21 @@ let
# 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 =
+ nvidiaForKernel = kernelPackages:
if elem "nvidia" drivers then
- config.boot.kernelPackages.nvidia_x11
+ kernelPackages.nvidia_x11
else if elem "nvidiaLegacy173" drivers then
- config.boot.kernelPackages.nvidia_x11_legacy173
+ kernelPackages.nvidia_x11_legacy173
else if elem "nvidiaLegacy304" drivers then
- config.boot.kernelPackages.nvidia_x11_legacy304
- else throw "impossible";
+ kernelPackages.nvidia_x11_legacy304
+ else if elem "nvidiaLegacy340" drivers then
+ kernelPackages.nvidia_x11_legacy340
+ else null;
+ nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
+ nvidia_libs32 = (nvidiaForKernel pkgs_i686.linuxPackages).override { libsOnly = true; kernel = null; };
+
+ enabled = nvidia_x11 != null;
in
{
@@ -37,12 +41,21 @@ in
'';
hardware.opengl.package = nvidia_x11;
- hardware.opengl.package32 = pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; };
+ hardware.opengl.package32 = nvidia_libs32;
environment.systemPackages = [ nvidia_x11 ];
boot.extraModulePackages = [ nvidia_x11 ];
+ # nvidia-uvm is required by CUDA applications.
+ boot.kernelModules = [ "nvidia-uvm" ];
+
+ # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
+ services.udev.extraRules =
+ ''
+ KERNEL=="nvidia_uvm", RUN+="${pkgs.stdenv.shell} -c 'mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'"
+ '';
+
boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ];
services.acpid.enable = true;
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
index 4d87c20559d..4896eee2908 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -36,12 +36,21 @@ with lib;
# EFI booting
isoImage.makeEfiBootable = true;
+ # USB booting
+ isoImage.makeUsbBootable = true;
+
# Add Memtest86+ to the CD.
boot.loader.grub.memtest86.enable = true;
# Get a console as soon as the initrd loads fbcon on EFI boot.
boot.initrd.kernelModules = [ "fbcon" ];
+ # Add support for cow filesystems and their utilities
+ boot.supportedFilesystems = [ "zfs" "btrfs" ];
+
+ # Configure host id for ZFS to work
+ networking.hostId = "8425e349";
+
# Allow the user to log in as root without a password.
- security.initialRootPassword = "";
+ users.extraUsers.root.initialHashedPassword = "";
}
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix
index 65aa1167089..189cca9e23b 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical.nix
@@ -11,6 +11,13 @@ with lib;
# Provide wicd for easy wireless configuration.
#networking.wicd.enable = true;
+ # Include gparted for partitioning disks
+ environment.systemPackages = [ pkgs.gparted ];
+
+ # Provide networkmanager for easy wireless configuration.
+ networking.networkmanager.enable = true;
+ networking.wireless.enable = mkForce false;
+
# KDE complains if power management is disabled (to be precise, if
# there is no power management backend such as upower).
powerManagement.enable = true;
@@ -27,4 +34,70 @@ with lib;
AutoLoginUser=root
AutoLoginPass=""
'';
+
+ # Custom kde-workspace adding some icons on the desktop
+
+ system.activationScripts.installerDesktop = let
+ openManual = pkgs.writeScript "nixos-manual.sh" ''
+ #!${pkgs.stdenv.shell}
+ cd ${config.system.build.manual.manual}/share/doc/nixos/
+ konqueror ./index.html
+ '';
+
+ desktopFile = pkgs.writeText "nixos-manual.desktop" ''
+ [Desktop Entry]
+ Version=1.0
+ Type=Application
+ Name=NixOS Manual
+ Exec=${openManual}
+ Icon=konqueror
+ '';
+
+ in ''
+ mkdir -p /root/Desktop
+ ln -sfT ${desktopFile} /root/Desktop/nixos-manual.desktop
+ ln -sfT ${pkgs.kde4.konsole}/share/applications/kde4/konsole.desktop /root/Desktop/konsole.desktop
+ ln -sfT ${pkgs.gparted}/share/applications/gparted.desktop /root/Desktop/gparted.desktop
+ '';
+
+ services.xserver.desktopManager.kde4.kdeWorkspacePackage = let
+ pkg = pkgs.kde4.kde_workspace;
+
+ plasmaInit = pkgs.writeText "00-defaultLayout.js" ''
+ loadTemplate("org.kde.plasma-desktop.defaultPanel")
+
+ for (var i = 0; i < screenCount; ++i) {
+ var desktop = new Activity
+ desktop.name = i18n("Desktop")
+ desktop.screen = i
+ desktop.wallpaperPlugin = 'image'
+ desktop.wallpaperMode = 'SingleImage'
+
+ var folderview = desktop.addWidget("folderview");
+ folderview.writeConfig("url", "desktop:/");
+
+ //Create more panels for other screens
+ if (i > 0){
+ var panel = new Panel
+ panel.screen = i
+ panel.location = 'bottom'
+ panel.height = screenGeometry(i).height > 1024 ? 35 : 27
+ var tasks = panel.addWidget("tasks")
+ tasks.writeConfig("showOnlyCurrentScreen", true);
+ }
+ }
+ '';
+
+ in
+ pkgs.stdenv.mkDerivation {
+ inherit (pkg) name meta;
+
+ buildCommand = ''
+ mkdir -p $out
+ cp -prf ${pkg}/* $out/
+ chmod a+w $out/share/apps/plasma-desktop/init
+ cp -f ${plasmaInit} $out/share/apps/plasma-desktop/init/00-defaultLayout.js
+ '';
+ };
+
}
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index 623cfdedd26..d9d7254aba2 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -7,66 +7,89 @@
with lib;
let
+ # Timeout in syslinux is in units of 1/10 of a second.
+ # 0 is used to disable timeouts.
+ syslinuxTimeout = if config.boot.loader.timeout == null then
+ 0
+ else
+ max (config.boot.loader.timeout * 10) 1;
- # The Grub image.
- grubImage = pkgs.runCommand "grub_eltorito" {}
+
+ max = x: y: if x > y then x else y;
+
+ # The configuration file for syslinux.
+
+ # Notes on syslinux configuration and UNetbootin compatiblity:
+ # * Do not use '/syslinux/syslinux.cfg' as the path for this
+ # configuration. UNetbootin will not parse the file and use it as-is.
+ # This results in a broken configuration if the partition label does
+ # not match the specified config.isoImage.volumeID. For this reason
+ # we're using '/isolinux/isolinux.cfg'.
+ # * Use APPEND instead of adding command-line arguments directly after
+ # the LINUX entries.
+ # * COM32 entries (chainload, reboot, poweroff) are not recognized. They
+ # result in incorrect boot entries.
+
+ baseIsolinuxCfg =
''
- ${pkgs.grub2}/bin/grub-mkimage -O i386-pc -o tmp biosdisk iso9660 help linux linux16 chain png jpeg echo gfxmenu reboot
- cat ${pkgs.grub2}/lib/grub/*/cdboot.img tmp > $out
- ''; # */
+ SERIAL 0 38400
+ TIMEOUT ${builtins.toString syslinuxTimeout}
+ UI vesamenu.c32
+ MENU TITLE NixOS
+ MENU BACKGROUND /isolinux/background.png
+ DEFAULT boot
-
- # The configuration file for Grub.
- grubCfg =
- ''
- set default=${builtins.toString config.boot.loader.grub.default}
- set timeout=${builtins.toString config.boot.loader.grub.timeout}
-
- if loadfont /boot/grub/unicode.pf2; then
- set gfxmode=640x480
- insmod gfxterm
- insmod vbe
- terminal_output gfxterm
-
- insmod png
- if background_image /boot/grub/splash.png; then
- set color_normal=white/black
- set color_highlight=black/white
- else
- set menu_color_normal=cyan/blue
- set menu_color_highlight=white/blue
- fi
-
- fi
-
- ${config.boot.loader.grub.extraEntries}
+ LABEL boot
+ MENU LABEL NixOS ${config.system.nixosVersion} Installer
+ LINUX /boot/bzImage
+ APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+ INITRD /boot/initrd
'';
+ isolinuxMemtest86Entry = ''
+ LABEL memtest
+ MENU LABEL Memtest86+
+ LINUX /boot/memtest.bin
+ APPEND ${toString config.boot.loader.grub.memtest86.params}
+ '';
+
+ isolinuxCfg = baseIsolinuxCfg + (optionalString config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
# The efi boot image
efiDir = pkgs.runCommand "efi-directory" {} ''
- mkdir -p $out/efi/boot
- cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/efi/boot/boot${targetArch}.efi
+ mkdir -p $out/EFI/boot
+ cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/EFI/boot/boot${targetArch}.efi
mkdir -p $out/loader/entries
echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf
echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf
echo "default nixos-livecd" > $out/loader/loader.conf
- echo "timeout 5" >> $out/loader/loader.conf
+ echo "timeout ${builtins.toString config.boot.loader.gummiboot.timeout}" >> $out/loader/loader.conf
'';
- efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; }
+ efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools pkgs.libfaketime ]; }
+ # Be careful about determinism: du --apparent-size,
+ # dates (cp -p, touch, mcopy -m, faketime for label), IDs (mkfs.vfat -i)
''
- #Let's hope 10M is enough
- dd bs=2048 count=5120 if=/dev/zero of="$out"
- ${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
- mcopy -svi "$out" ${efiDir}/* ::
- mmd -i "$out" boot
- mcopy -v -i "$out" \
- ${config.boot.kernelPackages.kernel}/bzImage ::boot/bzImage
- mcopy -v -i "$out" \
- ${config.system.build.initialRamdisk}/initrd ::boot/initrd
+ mkdir ./contents && cd ./contents
+ cp -rp "${efiDir}"/* .
+ mkdir ./boot
+ cp -p "${config.boot.kernelPackages.kernel}/bzImage" \
+ "${config.system.build.initialRamdisk}/initrd" ./boot/
+ touch --date=@0 ./*
+
+ usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
+ # Make the image 110% as big as the files need to make up for FAT overhead
+ image_size=$(( ($usage_size * 110) / 100 ))
+ # Make the image fit blocks of 1M
+ block_size=$((1024*1024))
+ image_size=$(( ($image_size / $block_size + 1) * $block_size ))
+ echo "Usage size: $usage_size"
+ echo "Image size: $image_size"
+ truncate --size=$image_size "$out"
+ ${pkgs.libfaketime}/bin/faketime "2000-01-01 00:00:00" ${pkgs.dosfstools}/sbin/mkfs.vfat -i 12345678 -n EFIBOOT "$out"
+ mcopy -bpsvm -i "$out" ./* ::
''; # */
targetArch = if pkgs.stdenv.isi686 then
@@ -152,10 +175,25 @@ in
'';
};
+ isoImage.makeUsbBootable = mkOption {
+ default = false;
+ description = ''
+ Whether the ISO image should be bootable from CD as well as USB.
+ '';
+ };
+
+ isoImage.splashImage = mkOption {
+ default = pkgs.fetchurl {
+ url = https://raw.githubusercontent.com/NixOS/nixos-artwork/5729ab16c6a5793c10a2913b5a1b3f59b91c36ee/ideas/grub-splash/grub-nixos-1.png;
+ sha256 = "43fd8ad5decf6c23c87e9026170a13588c2eba249d9013cb9f888da5e2002217";
+ };
+ description = ''
+ The splash image to use in the bootloader.
+ '';
+ };
};
-
config = {
boot.loader.grub.version = 2;
@@ -166,7 +204,7 @@ in
# !!! Hack - attributes expected by other modules.
system.boot.loader.kernelFile = "bzImage";
- environment.systemPackages = [ pkgs.grub2 ];
+ environment.systemPackages = [ pkgs.grub2 pkgs.syslinux ];
# In stage 1 of the boot, mount the CD as the root FS by label so
# that we don't need to know its device. We pass the label of the
@@ -176,7 +214,10 @@ in
# UUID of the USB stick. It would be nicer to write
# `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
# recognise that.
- boot.kernelParams = [ "root=LABEL=${config.isoImage.volumeID}" ];
+ boot.kernelParams =
+ [ "root=LABEL=${config.isoImage.volumeID}"
+ "boot.shell_on_fail"
+ ];
fileSystems."/" =
{ fsType = "tmpfs";
@@ -213,7 +254,7 @@ in
options = "allow_other,cow,nonempty,chroot=/mnt-root,max_files=32768,hide_meta_files,dirs=/nix/.rw-store=rw:/nix/.ro-store=ro";
};
- boot.initrd.availableKernelModules = [ "squashfs" "iso9660" ];
+ boot.initrd.availableKernelModules = [ "squashfs" "iso9660" "usb-storage" ];
boot.initrd.kernelModules = [ "loop" ];
@@ -233,15 +274,12 @@ in
# Individual files to be included on the CD, outside of the Nix
# store on the CD.
isoImage.contents =
- [ { source = grubImage;
- target = "/boot/grub/grub_eltorito";
- }
- { source = pkgs.substituteAll {
- name = "grub.cfg";
- src = pkgs.writeText "grub.cfg-in" grubCfg;
+ [ { source = pkgs.substituteAll {
+ name = "isolinux.cfg";
+ src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
bootRoot = "/boot";
};
- target = "/boot/grub/grub.cfg";
+ target = "/isolinux/isolinux.cfg";
}
{ source = config.boot.kernelPackages.kernel + "/bzImage";
target = "/boot/bzImage";
@@ -249,51 +287,44 @@ in
{ source = config.system.build.initialRamdisk + "/initrd";
target = "/boot/initrd";
}
- { source = "${pkgs.grub2}/share/grub/unicode.pf2";
- target = "/boot/grub/unicode.pf2";
- }
- { source = config.boot.loader.grub.splashImage;
- target = "/boot/grub/splash.png";
- }
{ source = config.system.build.squashfsStore;
target = "/nix-store.squashfs";
}
+ { source = "${pkgs.syslinux}/share/syslinux";
+ target = "/isolinux";
+ }
+ { source = config.isoImage.splashImage;
+ target = "/isolinux/background.png";
+ }
] ++ optionals config.isoImage.makeEfiBootable [
{ source = efiImg;
target = "/boot/efi.img";
}
- { source = "${efiDir}/efi";
- target = "/efi";
+ { source = "${efiDir}/EFI";
+ target = "/EFI";
}
{ source = "${efiDir}/loader";
target = "/loader";
}
- ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles;
-
- # The Grub menu.
- boot.loader.grub.extraEntries =
- ''
- menuentry "NixOS ${config.system.nixosVersion} Installer" {
- linux /boot/bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
- initrd /boot/initrd
+ ] ++ optionals config.boot.loader.grub.memtest86.enable [
+ { source = "${pkgs.memtest86plus}/memtest.bin";
+ target = "/boot/memtest.bin";
}
+ ];
- menuentry "Boot from hard disk" {
- set root=(hd0)
- chainloader +1
- }
- '';
-
- boot.loader.grub.timeout = 10;
+ boot.loader.timeout = 10;
# Create the ISO image.
system.build.isoImage = import ../../../lib/make-iso9660-image.nix ({
- inherit (pkgs) stdenv perl cdrkit pathsFromGraph;
+ inherit (pkgs) stdenv perl pathsFromGraph xorriso syslinux;
inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = true;
- bootImage = "/boot/grub/grub_eltorito";
+ bootImage = "/isolinux/isolinux.bin";
+ } // optionalAttrs config.isoImage.makeUsbBootable {
+ usbBootable = true;
+ isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
} // optionalAttrs config.isoImage.makeEfiBootable {
efiBootable = true;
efiBootImage = "boot/efi.img";
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
index c2a11a1a8b3..bbf0311c04d 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball-fuloong2f.nix
@@ -76,10 +76,8 @@ in
pkgs.ntfsprogs # for resizing NTFS partitions
pkgs.btrfsProgs
pkgs.jfsutils
- pkgs.jfsrec
# Some compression/archiver tools.
- pkgs.unrar
pkgs.unzip
pkgs.zip
pkgs.xz
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt b/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
index 8f0a8d355c6..84252f292c5 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
+++ b/nixos/modules/installer/cd-dvd/system-tarball-pc-readme.txt
@@ -80,7 +80,7 @@ had booted this nixos. Run:
* `grep local-cmds run/current-system/init`
Then you can proceed normally subscribing to a nixos channel:
- nix-channel --add http://nixos.org/channels/nixos-unstable
+ nix-channel --add https://nixos.org/channels/nixos-unstable
nix-channel --update
Testing:
diff --git a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
index 2ed70c1daa9..46dc1c70502 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball-sheevaplug.nix
@@ -70,7 +70,6 @@ in
pkgs.btrfsProgs
# Some compression/archiver tools.
- pkgs.unrar
pkgs.unzip
pkgs.zip
pkgs.xz
@@ -99,7 +98,7 @@ in
boot.initrd.extraUtilsCommands =
''
- cp ${pkgs.utillinux}/sbin/hwclock $out/bin
+ copy_bin_and_libs ${pkgs.utillinux}/sbin/hwclock
'';
boot.initrd.postDeviceCommands =
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 93a348f2717..eadaae6715b 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -22,7 +22,7 @@ sub uniq {
sub runCommand {
my ($cmd) = @_;
- open FILE, "$cmd 2>/dev/null |" or die "Failed to execute: $cmd\n";
+ open FILE, "$cmd 2>&1 |" or die "Failed to execute: $cmd\n";
my @ret = ;
close FILE;
return ($?, @ret);
@@ -148,7 +148,7 @@ sub pciCheck {
$device eq "0x4331" || $device eq "0x43a0" || $device eq "0x43b1"
) )
{
- push @modulePackages, "config.boot.kernelPackages.broadcom_sta";
+ push @modulePackages, "\${config.boot.kernelPackages.broadcom_sta}";
push @kernelModules, "wl";
}
@@ -235,7 +235,7 @@ chomp $virt;
# Check if we're a VirtualBox guest. If so, enable the guest
# additions.
if ($virt eq "oracle") {
- push @attrs, "services.virtualbox.enable = true;"
+ push @attrs, "services.virtualboxGuest.enable = true;"
}
@@ -311,10 +311,13 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
# Maybe this is a bind-mount of a filesystem we saw earlier?
if (defined $fsByDev{$fields[2]}) {
- my $path = $fields[3]; $path = "" if $path eq "/";
- my $base = $fsByDev{$fields[2]};
- $base = "" if $base eq "/";
- $fileSystems .= < 0) {
- die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
- } elsif ($#subvols == 0) {
- push @extraOptions, "subvol=$subvols[0]";
- }
- }
+ # Is this a btrfs filesystem?
+ if ($fsType eq "btrfs") {
+ my ($status, @id_info) = runCommand("btrfs subvol show $rootDir$mountPoint");
+ if ($status != 0 || join("", @msg) =~ /ERROR:/) {
+ die "Failed to retreive subvolume info for $mountPoint\n";
+ }
+ my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
+ if ($#ids > 0) {
+ die "Btrfs subvol name for $mountPoint listed multiple times in mount\n"
+ } elsif ($#ids == 0) {
+ my ($status, @path_info) = runCommand("btrfs subvol list $rootDir$mountPoint");
+ if ($status != 0) {
+ die "Failed to find $mountPoint subvolume id from btrfs\n";
+ }
+ my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
+ if ($#paths > 0) {
+ die "Btrfs returned multiple paths for a single subvolume id, mountpoint $mountPoint\n";
+ } elsif ($#paths != 0) {
+ die "Btrfs did not return a path for the subvolume at $mountPoint\n";
+ }
+ push @extraOptions, "subvol=$paths[0]";
+ }
+ }
# Emit the filesystem.
$fileSystems .= <
# * install the boot loader
+# Ensure a consistent umask.
+umask 0022
+
# Re-exec ourselves in a private mount namespace so that our bind
# mounts get cleaned up automatically.
if [ "$(id -u)" = 0 ]; then
@@ -25,10 +28,14 @@ chrootCommand=(/run/current-system/sw/bin/bash)
while [ "$#" -gt 0 ]; do
i="$1"; shift 1
case "$i" in
- -I)
- given_path="$1"; shift 1
- absolute_path=$(readlink -m $given_path)
- extraBuildFlags+=("$i" "/mnt$absolute_path")
+ --max-jobs|-j|--cores|-I)
+ j="$1"; shift 1
+ extraBuildFlags+=("$i" "$j")
+ ;;
+ --option)
+ j="$1"; shift 1
+ k="$1"; shift 1
+ extraBuildFlags+=("$i" "$j" "$k")
;;
--root)
mountPoint="$1"; shift 1
@@ -75,6 +82,7 @@ mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/et
mkdir -m 01777 -p $mountPoint/tmp
mkdir -m 0755 -p $mountPoint/tmp/root
mkdir -m 0755 -p $mountPoint/var/setuid-wrappers
+mkdir -m 0700 -p $mountPoint/root
mount --rbind /dev $mountPoint/dev
mount --rbind /proc $mountPoint/proc
mount --rbind /sys $mountPoint/sys
@@ -86,6 +94,12 @@ ln -s /run $mountPoint/var/run
rm -f $mountPoint/etc/{resolv.conf,hosts}
cp -Lf /etc/resolv.conf /etc/hosts $mountPoint/etc/
+if [ -e "$SSL_CERT_FILE" ]; then
+ cp -Lf "$SSL_CERT_FILE" "$mountPoint/tmp/ca-cert.crt"
+ export SSL_CERT_FILE=/tmp/ca-cert.crt
+ # For Nix 1.7
+ export CURL_CA_BUNDLE=/tmp/ca-cert.crt
+fi
if [ -n "$runChroot" ]; then
if ! [ -L $mountPoint/nix/var/nix/profiles/system ]; then
@@ -241,9 +255,9 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate
# Ask the user to set a root password.
-if [ -t 0 ] ; then
+if [ "$(chroot $mountPoint nix-instantiate --eval '' -A config.users.mutableUsers)" = true ] && [ -t 0 ] ; then
echo "setting root password..."
- chroot $mountPoint passwd
+ chroot $mountPoint /var/setuid-wrappers/passwd
fi
diff --git a/nixos/modules/installer/tools/nixos-option.sh b/nixos/modules/installer/tools/nixos-option.sh
index edc94d73208..17c17d05e28 100644
--- a/nixos/modules/installer/tools/nixos-option.sh
+++ b/nixos/modules/installer/tools/nixos-option.sh
@@ -11,11 +11,9 @@ usage () {
# Process Arguments #
#####################
-desc=false
-defs=false
-value=false
xml=false
verbose=false
+nixPath=""
option=""
@@ -24,14 +22,12 @@ for arg; do
if test -z "$argfun"; then
case $arg in
-*)
- longarg=""
sarg="$arg"
+ longarg=""
while test "$sarg" != "-"; do
case $sarg in
--*) longarg=$arg; sarg="--";;
- -d*) longarg="$longarg --description";;
- -v*) longarg="$longarg --value";;
- -l*) longarg="$longarg --lookup";;
+ -I) argfun="include_nixpath";;
-*) usage;;
esac
# remove the first letter option
@@ -42,9 +38,6 @@ for arg; do
esac
for larg in $longarg; do
case $larg in
- --description) desc=true;;
- --value) value=true;;
- --lookup) defs=true;;
--xml) xml=true;;
--verbose) verbose=true;;
--help) usage;;
@@ -62,21 +55,14 @@ for arg; do
var=$(echo $argfun | sed 's,^set_,,')
eval $var=$arg
;;
+ include_nixpath)
+ nixPath="-I $arg $nixPath"
+ ;;
esac
argfun=""
fi
done
-if $xml; then
- value=true
- desc=true
- defs=true
-fi
-
-if ! $defs && ! $desc; then
- value=true
-fi
-
if $verbose; then
set -x
else
@@ -88,19 +74,114 @@ fi
#############################
evalNix(){
- nix-instantiate - --eval-only "$@"
+ result=$(nix-instantiate ${nixPath:+$nixPath} - --eval-only "$@" 2>&1)
+ if test $? -eq 0; then
+ cat < {};
+ nixpkgs = import {};
+in with nixpkgs.lib;
+"
+
+# This function is used for converting the option definition path given by
+# the user into accessors for reaching the definition and the declaration
+# corresponding to this option.
+generateAccessors(){
+ if result=$(evalNix --strict --show-trace < {}).$prefix${option:+.$option}${suffix:+.$suffix}" |
- evalNix ${strict:+--strict}
+
+ # If strict is set, then set it to "true".
+ test -n "$strict" && strict=true
+
+ evalNix ${strict:+--strict} <"
+ else if strict then
+ if isAttrs x then mapAttrs (n: cleanOutput) x
+ else if isList x then map cleanOutput x
+ else x
+ else x;
+in
+ cleanOutput value
+EOF
}
evalOpt(){
- evalAttr "options" "" "$@"
+ evalAttr "option" "" "$@"
}
evalCfg(){
@@ -110,8 +191,11 @@ evalCfg(){
findSources(){
local suffix=$1
- echo "(import {}).options${option:+.$option}.$suffix" |
- evalNix --strict
+ evalNix --strict < {};
- nixpkgs = import {};
sources = builtins.map (f: f.source);
- opt = reach nixos.options;
- cfg = reach nixos.config;
+ opt = option;
+ cfg = config;
in
with nixpkgs.lib;
@@ -189,35 +272,37 @@ EOF
fi
if test "$(evalOpt "_type" 2> /dev/null)" = '"option"'; then
- $value && evalCfg 1
+ echo "Value:"
+ evalCfg 1
- if $desc; then
- $value && echo;
+ echo
- if default=$(evalOpt "default" - 2> /dev/null); then
- echo "Default: $default"
- else
- echo "Default: "
- fi
- if example=$(evalOpt "example" - 2> /dev/null); then
- echo "Example: $example"
- fi
- echo "Description:"
- eval printf $(evalOpt "description")
+ echo "Default:"
+ if default=$(evalOpt "default" - 2> /dev/null); then
+ echo "$default"
+ else
+ echo ""
fi
-
- if $defs; then
- $desc || $value && echo;
-
- printPath () { echo " $1"; }
-
- echo "Declared by:"
- nixMap printPath "$(findSources "declarations")"
- echo ""
- echo "Defined by:"
- nixMap printPath "$(findSources "files")"
- echo ""
+ echo
+ if example=$(evalOpt "example" - 2> /dev/null); then
+ echo "Example:"
+ echo "$example"
+ echo
fi
+ echo "Description:"
+ echo
+ eval printf $(evalOpt "description")
+
+ echo $desc;
+
+ printPath () { echo " $1"; }
+
+ echo "Declared by:"
+ nixMap printPath "$(findSources "declarations")"
+ echo
+ echo "Defined by:"
+ nixMap printPath "$(findSources "files")"
+ echo
else
# echo 1>&2 "Warning: This value is not an option."
diff --git a/nixos/modules/installer/tools/nixos-rebuild.sh b/nixos/modules/installer/tools/nixos-rebuild.sh
index 52b64c37578..1d6df8cb3f7 100644
--- a/nixos/modules/installer/tools/nixos-rebuild.sh
+++ b/nixos/modules/installer/tools/nixos-rebuild.sh
@@ -26,7 +26,8 @@ while [ "$#" -gt 0 ]; do
--help)
showSyntax
;;
- switch|boot|test|build|dry-run|build-vm|build-vm-with-bootloader)
+ switch|boot|test|build|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader)
+ if [ "$i" = dry-run ]; then i=dry-build; fi
action="$i"
;;
--install-grub)
@@ -137,7 +138,7 @@ fi
# First build Nix, since NixOS may require a newer version than the
# current one.
-if [ -n "$rollback" -o "$action" = dry-run ]; then
+if [ -n "$rollback" -o "$action" = dry-build ]; then
buildNix=
fi
@@ -148,15 +149,15 @@ if [ -n "$buildNix" ]; then
if ! nix-build '' -A nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
machine="$(uname -m)"
if [ "$machine" = x86_64 ]; then
- nixStorePath=/nix/store/d34q3q2zj9nriq4ifhn3dnnngqvinjb3-nix-1.7
+ nixStorePath=/nix/store/ffig6yaggbh12dh9y5pnf1grf5lqyipz-nix-1.8
elif [[ "$machine" =~ i.86 ]]; then
- nixStorePath=/nix/store/qlah0darpcn6sf3lr2226rl04l1gn4xz-nix-1.7
+ nixStorePath=/nix/store/lglhfp4mimfa5wzjjf1kqz6f5wlsj2mn-nix-1.8
else
echo "$0: unsupported platform"
exit 1
fi
if ! nix-store -r $nixStorePath --add-root $tmpDir/nix --indirect \
- --option extra-binary-caches http://cache.nixos.org/; then
+ --option extra-binary-caches https://cache.nixos.org/; then
echo "warning: don't know how to get latest Nix" >&2
fi
# Older version of nix-store -r don't support --add-root.
@@ -180,7 +181,7 @@ if [ -n "$canRun" ]; then
fi
-if [ "$action" = dry-run ]; then
+if [ "$action" = dry-build ]; then
extraBuildFlags+=(--dry-run)
fi
@@ -193,14 +194,14 @@ if [ -z "$rollback" ]; then
if [ "$action" = switch -o "$action" = boot ]; then
nix-env "${extraBuildFlags[@]}" -p "$profile" -f '' --set -A system
pathToConfig="$profile"
- elif [ "$action" = test -o "$action" = build -o "$action" = dry-run ]; then
- nix-build '' -A system -K -k "${extraBuildFlags[@]}" > /dev/null
+ elif [ "$action" = test -o "$action" = build -o "$action" = dry-build -o "$action" = dry-activate ]; then
+ nix-build '' -A system -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
elif [ "$action" = build-vm ]; then
- nix-build '' -A vm -K -k "${extraBuildFlags[@]}" > /dev/null
+ nix-build '' -A vm -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
elif [ "$action" = build-vm-with-bootloader ]; then
- nix-build '' -A vmWithBootLoader -K -k "${extraBuildFlags[@]}" > /dev/null
+ nix-build '' -A vmWithBootLoader -k "${extraBuildFlags[@]}" > /dev/null
pathToConfig=./result
else
showSyntax
@@ -224,9 +225,9 @@ fi
# If we're not just building, then make the new configuration the boot
# default and/or activate it now.
-if [ "$action" = switch -o "$action" = boot -o "$action" = test ]; then
+if [ "$action" = switch -o "$action" = boot -o "$action" = test -o "$action" = dry-activate ]; then
if ! $pathToConfig/bin/switch-to-configuration "$action"; then
- echo "warning: there were error switching to the new configuration" >&2
+ echo "warning: error(s) occured while switching to the new configuration" >&2
exit 1
fi
fi
diff --git a/nixos/modules/installer/tools/nixos-version.sh b/nixos/modules/installer/tools/nixos-version.sh
index 5dbf277fe4c..51aa2dd8232 100644
--- a/nixos/modules/installer/tools/nixos-version.sh
+++ b/nixos/modules/installer/tools/nixos-version.sh
@@ -1,2 +1,10 @@
#! @shell@
-echo "@nixosVersion@ (@nixosCodeName@)"
+
+case "$1" in
+ --hash|--revision)
+ echo "@nixosRevision@"
+ ;;
+ *)
+ echo "@nixosVersion@ (@nixosCodeName@)"
+ ;;
+esac
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index 91a30695a7a..99a74b6d59e 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -1,7 +1,7 @@
# This module generates nixos-install, nixos-rebuild,
# nixos-generate-config, etc.
-{ config, pkgs, modulesPath, lib, ... }:
+{ config, pkgs, modulesPath, ... }:
let
@@ -50,49 +50,12 @@ let
nixos-version = makeProg {
name = "nixos-version";
src = ./nixos-version.sh;
- inherit (config.system) nixosVersion nixosCodeName;
+ inherit (config.system) nixosVersion nixosCodeName nixosRevision;
};
- /*
- nixos-gui = pkgs.xulrunnerWrapper {
- launcher = "nixos-gui";
- application = pkgs.stdenv.mkDerivation {
- name = "nixos-gui";
- buildCommand = ''
- cp -r "$gui" "$out"
-
- # Do not force the copy if the file exists in the sources (this
- # happens for developpers)
- test -e "$out/chrome/content/jquery-1.5.2.js" ||
- cp -f "$jquery" "$out/chrome/content/jquery-1.5.2.js"
- '';
- gui = lib.cleanSource "${modulesPath}/../gui";
- jquery = pkgs.fetchurl {
- url = http://code.jquery.com/jquery-1.5.2.min.js;
- sha256 = "8f0a19ee8c606b35a10904951e0a27da1896eafe33c6e88cb7bcbe455f05a24a";
- };
- };
- };
- */
-
in
{
- /*
- options = {
-
- installer.enableGraphicalTools = mkOption {
- default = false;
- type = types.bool;
- example = true;
- description = ''
- Enable the installation of graphical tools.
- '';
- };
-
- };
- */
-
config = {
environment.systemPackages =
[ nixos-build-vms
diff --git a/nixos/modules/misc/check-config.nix b/nixos/modules/misc/check-config.nix
deleted file mode 100644
index e9803de2196..00000000000
--- a/nixos/modules/misc/check-config.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{ lib, ... }:
-
-with lib;
-
-{
- options = {
- environment.checkConfigurationOptions = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether to check the validity of the entire configuration.
- '';
- };
- };
-}
diff --git a/nixos/modules/misc/extra-arguments.nix b/nixos/modules/misc/extra-arguments.nix
new file mode 100644
index 00000000000..c2c8903546d
--- /dev/null
+++ b/nixos/modules/misc/extra-arguments.nix
@@ -0,0 +1,14 @@
+{ lib, pkgs, config, ... }:
+
+{
+ _module.args = {
+ modulesPath = ../.;
+
+ pkgs_i686 = import ../../lib/nixpkgs.nix {
+ system = "i686-linux";
+ config.allowUnfree = true;
+ };
+
+ utils = import ../../lib/utils.nix pkgs;
+ };
+}
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 513da5d50a1..c2523a3cc32 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -27,28 +27,38 @@
ids.uids = {
root = 0;
- nscd = 1;
- sshd = 2;
- ntp = 3;
+ #wheel = 1; # unused
+ #kmem = 2; # unused
+ #tty = 3; # unused
messagebus = 4; # D-Bus
haldaemon = 5;
- nagios = 6;
+ #disk = 6; # unused
vsftpd = 7;
ftp = 8;
bitlbee = 9;
avahi = 10;
+ nagios = 11;
atd = 12;
- zabbix = 13;
- postfix = 14;
+ postfix = 13;
+ #postdrop = 14; # unused
dovecot = 15;
tomcat = 16;
+ #audio = 17; # unused
+ #floppy = 18; # unused
+ #uucp = 19; # unused
+ #lp = 20; # unused
pulseaudio = 22; # must match `pulseaudio' GID
gpsd = 23;
+ #cdrom = 24; # unused
+ #tape = 25; # unused
+ #video = 26; # unused
+ #dialout = 27; # unused
polkituser = 28;
- uptimed = 29;
+ #utmp = 29; # unused
ddclient = 30;
davfs2 = 31;
privoxy = 32;
+ #disnix = 33; # unused
osgi = 34;
tor = 35;
cups = 36;
@@ -70,19 +80,26 @@
fprot = 52;
bind = 53;
wwwrun = 54;
+ #adm = 55; # unused
spamd = 56;
+ #networkmanager = 57; # unused
nslcd = 58;
+ #scanner = 59; # unused
nginx = 60;
chrony = 61;
+ #systemd-journal = 62; # unused
smtpd = 63;
smtpq = 64;
supybot = 65;
iodined = 66;
+ #libvirtd = 67; # unused
graphite = 68;
statsd = 69;
transmission = 70;
postgres = 71;
- smbguest = 74;
+ #vboxusers = 72; # unused
+ #vboxsf = 73; # unused
+ smbguest = 74; # unused
varnish = 75;
datadog = 76;
lighttpd = 77;
@@ -102,13 +119,13 @@
minidlna = 91;
elasticsearch = 92;
tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice.
- zope2 = 94;
+ #connman = 94; # unused
firebird = 95;
- redis = 96;
+ #keys = 96; # unused
haproxy = 97;
mongodb = 98;
openldap = 99;
- memcached = 100;
+ #users = 100; # unused
cgminer = 101;
munin = 102;
logcheck = 103;
@@ -129,6 +146,7 @@
foundationdb = 118;
newrelic = 119;
starbound = 120;
+ #grsecurity = 121; # unused
hydra = 122;
spiped = 123;
teamspeak = 124;
@@ -138,7 +156,7 @@
znc = 128;
polipo = 129;
mopidy = 130;
- unifi = 131;
+ #docker = 131; # unused
gdm = 132;
dhcpd = 133;
siproxd = 134;
@@ -149,6 +167,53 @@
radvd = 139;
zookeeper = 140;
dnsmasq = 141;
+ uhub = 142;
+ yandexdisk = 143;
+ collectd = 144;
+ consul = 145;
+ mailpile = 146;
+ redmine = 147;
+ seeks = 148;
+ prosody = 149;
+ i2pd = 150;
+ dnscrypt-proxy = 151;
+ systemd-network = 152;
+ systemd-resolve = 153;
+ systemd-timesync = 154;
+ liquidsoap = 155;
+ etcd = 156;
+ docker-registry = 157;
+ hbase = 158;
+ opentsdb = 159;
+ scollector = 160;
+ bosun = 161;
+ kubernetes = 162;
+ peerflix = 163;
+ chronos = 164;
+ gitlab = 165;
+ tox-bootstrapd = 166;
+ cadvisor = 167;
+ nylon = 168;
+ apache-kafka = 169;
+ panamax = 170;
+ marathon = 171;
+ exim = 172;
+ #fleet = 173; # unused
+ #input = 174; # unused
+ sddm = 175;
+ tss = 176;
+ memcached = 177;
+ nscd = 178;
+ ntp = 179;
+ zabbix = 180;
+ redis = 181;
+ sshd = 182;
+ unifi = 183;
+ uptimed = 184;
+ zope2 = 185;
+ ripple-data-api = 186;
+ mediatomb = 187;
+ rdnssd = 188;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@@ -168,15 +233,16 @@
ftp = 8;
bitlbee = 9;
avahi = 10;
+ #nagios = 11; # unused
atd = 12;
postfix = 13;
postdrop = 14;
dovecot = 15;
+ tomcat = 16;
audio = 17;
floppy = 18;
uucp = 19;
lp = 20;
- tomcat = 21;
pulseaudio = 22; # must match `pulseaudio' UID
gpsd = 23;
cdrom = 24;
@@ -185,20 +251,30 @@
dialout = 27;
#polkituser = 28; # currently unused, polkitd doesn't need a group
utmp = 29;
+ #ddclient = 30; # unused
davfs2 = 31;
privoxy = 32;
disnix = 33;
osgi = 34;
- ghostOne = 40;
+ tor = 35;
+ #cups = 36; # unused
+ #foldingathome = 37; # unused
+ #sabnzd = 38; # unused
+ #kdm = 39; # unused
+ ghostone = 40;
git = 41;
fourstore = 42;
- fourstorehttpd = 43;
+ fourstorehttp = 43;
virtuoso = 44;
+ #rtkit = 45; # unused
dovecot2 = 46;
+ #dovenull = 47; # unused
+ #unbound = 48; # unused
prayer = 49;
mpd = 50;
clamav = 51;
fprot = 52;
+ #bind = 53; # unused
wwwrun = 54;
adm = 55;
spamd = 56;
@@ -206,6 +282,7 @@
nslcd = 58;
scanner = 59;
nginx = 60;
+ #chrony = 61; # unused
systemd-journal = 62;
smtpd = 63;
smtpq = 64;
@@ -213,11 +290,12 @@
iodined = 66;
libvirtd = 67;
graphite = 68;
+ #statsd = 69; # unused
transmission = 70;
postgres = 71;
vboxusers = 72;
vboxsf = 73;
- smbguest = 74;
+ smbguest = 74; # unused
varnish = 75;
datadog = 76;
lighttpd = 77;
@@ -235,11 +313,17 @@
quassel = 89;
amule = 90;
minidlna = 91;
- haproxy = 92;
- openldap = 93;
+ #elasticsearch = 92; # unused
+ #tcpcryptd = 93; # unused
connman = 94;
- munin = 95;
+ firebird = 95;
keys = 96;
+ haproxy = 97;
+ #mongodb = 98; # unused
+ openldap = 99;
+ munin = 102;
+ #logcheck = 103; # unused
+ #nix-ssh = 104; # unused
dictd = 105;
couchdb = 106;
searx = 107;
@@ -247,7 +331,12 @@
jenkins = 109;
systemd-journal-gateway = 110;
notbit = 111;
+ #ngircd = 112; # unused
+ btsync = 113;
+ #minecraft = 114; # unused
monetdb = 115;
+ #ripped = 116; # unused
+ #murmur = 117; # unused
foundationdb = 118;
newrelic = 119;
starbound = 120;
@@ -257,19 +346,69 @@
teamspeak = 124;
influxdb = 125;
nsd = 126;
- firebird = 127;
+ #gitolite = 127; # unused
znc = 128;
polipo = 129;
mopidy = 130;
docker = 131;
gdm = 132;
- tss = 133;
+ #dhcpcd = 133; # unused
siproxd = 134;
mlmmj = 135;
+ #neo4j = 136; # unused
riemann = 137;
riemanndash = 138;
+ #radvd = 139; # unused
+ #zookeeper = 140; # unused
+ #dnsmasq = 141; # unused
+ uhub = 142;
+ #yandexdisk = 143; # unused
+ #collectd = 144; # unused
+ #consul = 145; # unused
+ mailpile = 146;
+ redmine = 147;
+ seeks = 148;
+ prosody = 149;
+ i2pd = 150;
+ #dnscrypt-proxy = 151; # unused
+ systemd-network = 152;
+ systemd-resolve = 153;
+ systemd-timesync = 154;
+ liquidsoap = 155;
+ #etcd = 156; # unused
+ #docker-registry = 157; # unused
+ hbase = 158;
+ opentsdb = 159;
+ scollector = 160;
+ bosun = 161;
+ kubernetes = 162;
+ #peerflix = 163; # unused
+ #chronos = 164; # unused
+ gitlab = 165;
+ nylon = 168;
+ panamax = 170;
+ #marathon = 171; # unused
+ exim = 172;
+ fleet = 173;
+ input = 174;
+ sddm = 175;
+ tss = 176;
+ #memcached = 177; # unused
+ #nscd = 178; # unused
+ #ntp = 179; # unused
+ #zabbix = 180; # unused
+ #redis = 181; # unused
+ #sshd = 182; # unused
+ #unifi = 183; # unused
+ #uptimed = 184; # unused
+ #zope2 = 185; # unused
+ #ripple-data-api = 186; #unused
+ mediatomb = 187;
+ #rdnssd = 188; # unused
- # When adding a gid, make sure it doesn't match an existing uid. And don't use gids above 399!
+ # When adding a gid, make sure it doesn't match an existing
+ # uid. Users and groups with the same name should have equal
+ # uids and gids. Also, don't use gids above 399!
users = 100;
nixbld = 30000;
diff --git a/nixos/modules/misc/locate.nix b/nixos/modules/misc/locate.nix
index 7de63c60649..f3ed2aaba09 100644
--- a/nixos/modules/misc/locate.nix
+++ b/nixos/modules/misc/locate.nix
@@ -41,7 +41,7 @@ in {
output = mkOption {
type = types.path;
- default = /var/cache/locatedb;
+ default = "/var/cache/locatedb";
description = ''
The database file to build.
'';
diff --git a/nixos/modules/misc/meta.nix b/nixos/modules/misc/meta.nix
new file mode 100644
index 00000000000..22622706f2c
--- /dev/null
+++ b/nixos/modules/misc/meta.nix
@@ -0,0 +1,63 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+ maintainer = mkOptionType {
+ name = "maintainer";
+ check = email: elem email (attrValues lib.maintainers);
+ merge = loc: defs: listToAttrs (singleton (nameValuePair (last defs).file (last defs).value));
+ };
+
+ listOfMaintainers = types.listOf maintainer // {
+ # Returns list of
+ # { "module-file" = [
+ # "maintainer1 "
+ # "maintainer2 " ];
+ # }
+ merge = loc: defs:
+ zipAttrs
+ (flatten (imap (n: def: imap (m: def':
+ maintainer.merge (loc ++ ["[${toString n}-${toString m}]"])
+ [{ inherit (def) file; value = def'; }]) def.value) defs));
+ };
+
+ docFile = types.path // {
+ # Returns tuples of
+ # { file = "module location"; value = ; }
+ merge = loc: defs: defs;
+ };
+in
+
+{
+ options = {
+ meta = {
+
+ maintainers = mkOption {
+ type = listOfMaintainers;
+ internal = true;
+ default = [];
+ example = [ lib.maintainers.all ];
+ description = ''
+ List of maintainers of each module. This option should be defined at
+ most once per module.
+ '';
+ };
+
+ doc = mkOption {
+ type = docFile;
+ internal = true;
+ example = "./meta.xml";
+ description = ''
+ Documentation prologe for the set of options of each module. This
+ option should be defined at most once per module.
+ '';
+ };
+
+ };
+ };
+
+ config = {
+ meta.maintainers = singleton lib.maintainers.pierron;
+ };
+}
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index f41c8817ba4..114feb2562d 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -59,7 +59,8 @@ in
};
nixpkgs.system = mkOption {
- type = types.str;
+ type = types.uniq types.str;
+ example = "i686-linux";
description = ''
Specifies the Nix platform type for which NixOS should be built.
If unset, it defaults to the platform type of your host system.
@@ -71,6 +72,10 @@ in
};
config = {
- nixpkgs.system = mkDefault pkgs.stdenv.system;
+ _module.args.pkgs = import ../../lib/nixpkgs.nix {
+ system = config.nixpkgs.system;
+
+ inherit (config.nixpkgs) config;
+ };
};
}
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index f4271cea853..5afdcf214f2 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -53,7 +53,7 @@ with lib;
mkDefault (if pathExists fn then readFile fn else "master");
# Note: code names must only increase in alphabetical order.
- system.nixosCodeName = "Caterpillar";
+ system.nixosCodeName = "Dingo";
# Generate /etc/os-release. See
# http://0pointer.de/public/systemd-man/os-release.html for the
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 853961804e5..17717c5988d 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1,6 +1,7 @@
[
./config/fonts/corefonts.nix
./config/fonts/fontconfig.nix
+ ./config/fonts/fontconfig-ultimate.nix
./config/fonts/fontdir.nix
./config/fonts/fonts.nix
./config/fonts/ghostscript.nix
@@ -21,12 +22,14 @@
./config/system-environment.nix
./config/system-path.nix
./config/timezone.nix
+ ./config/vpnc.nix
./config/unix-odbc-drivers.nix
./config/users-groups.nix
./config/zram.nix
./hardware/all-firmware.nix
./hardware/cpu/amd-microcode.nix
./hardware/cpu/intel-microcode.nix
+ ./hardware/ksm.nix
./hardware/network/b43.nix
./hardware/network/intel-2100bg.nix
./hardware/network/intel-2200bg.nix
@@ -37,24 +40,29 @@
./hardware/pcmcia.nix
./hardware/video/bumblebee.nix
./hardware/video/nvidia.nix
+ ./hardware/video/ati.nix
./installer/tools/nixos-checkout.nix
./installer/tools/tools.nix
./misc/assertions.nix
- ./misc/check-config.nix
./misc/crashdump.nix
+ ./misc/extra-arguments.nix
./misc/ids.nix
./misc/lib.nix
./misc/locate.nix
+ ./misc/meta.nix
./misc/nixpkgs.nix
./misc/passthru.nix
./misc/version.nix
./programs/atop.nix
./programs/bash/bash.nix
- ./programs/bash/command-not-found.nix
./programs/blcr.nix
+ ./programs/cdemu.nix
+ ./programs/command-not-found/command-not-found.nix
./programs/dconf.nix
./programs/environment.nix
./programs/info.nix
+ ./programs/ibus.nix
+ ./programs/light.nix
./programs/nano.nix
./programs/screen.nix
./programs/shadow.nix
@@ -63,6 +71,7 @@
./programs/ssmtp.nix
./programs/uim.nix
./programs/venus.nix
+ ./programs/virtualbox-host.nix
./programs/wvdial.nix
./programs/freetds.nix
./programs/zsh/zsh.nix
@@ -83,29 +92,41 @@
./services/amqp/activemq/default.nix
./services/amqp/rabbitmq.nix
./services/audio/alsa.nix
- ./services/audio/fuppes.nix
+ # Disabled as fuppes no longer builds.
+ # ./services/audio/fuppes.nix
+ ./services/audio/icecast.nix
+ ./services/audio/liquidsoap.nix
./services/audio/mpd.nix
./services/audio/mopidy.nix
./services/backup/almir.nix
./services/backup/bacula.nix
+ ./services/backup/crashplan.nix
./services/backup/mysql-backup.nix
./services/backup/postgresql-backup.nix
./services/backup/rsnapshot.nix
./services/backup/sitecopy-backup.nix
./services/backup/tarsnap.nix
+ ./services/cluster/fleet.nix
+ ./services/cluster/kubernetes.nix
+ ./services/cluster/panamax.nix
+ ./services/computing/torque/server.nix
+ ./services/computing/torque/mom.nix
+ ./services/computing/slurm/slurm.nix
./services/continuous-integration/jenkins/default.nix
./services/continuous-integration/jenkins/slave.nix
./services/databases/4store-endpoint.nix
./services/databases/4store.nix
./services/databases/couchdb.nix
./services/databases/firebird.nix
+ ./services/databases/hbase.nix
./services/databases/influxdb.nix
./services/databases/memcached.nix
./services/databases/monetdb.nix
./services/databases/mongodb.nix
./services/databases/mysql.nix
- ./services/databases/neo4j.nix
+ ./services/databases/neo4j.nix
./services/databases/openldap.nix
+ ./services/databases/opentsdb.nix
./services/databases/postgresql.nix
./services/databases/redis.nix
./services/databases/virtuoso.nix
@@ -122,21 +143,27 @@
./services/desktops/gnome3/seahorse.nix
./services/desktops/gnome3/sushi.nix
./services/desktops/gnome3/tracker.nix
+ ./services/desktops/profile-sync-daemon.nix
./services/desktops/telepathy.nix
./services/games/ghost-one.nix
./services/games/minecraft-server.nix
+ ./services/games/minetest-server.nix
./services/hardware/acpid.nix
./services/hardware/amd-hybrid-graphics.nix
./services/hardware/bluetooth.nix
+ ./services/hardware/freefall.nix
./services/hardware/nvidia-optimus.nix
./services/hardware/pcscd.nix
./services/hardware/pommed.nix
./services/hardware/sane.nix
./services/hardware/tcsd.nix
+ ./services/hardware/tlp.nix
./services/hardware/thinkfan.nix
./services/hardware/udev.nix
./services/hardware/udisks2.nix
./services/hardware/upower.nix
+ ./services/hardware/thermald.nix
+ ./services/logging/fluentd.nix
./services/logging/klogd.nix
./services/logging/logcheck.nix
./services/logging/logrotate.nix
@@ -145,31 +172,49 @@
./services/logging/syslogd.nix
./services/logging/syslog-ng.nix
./services/mail/dovecot.nix
+ ./services/mail/exim.nix
./services/mail/freepops.nix
./services/mail/mail.nix
./services/mail/mlmmj.nix
./services/mail/opensmtpd.nix
./services/mail/postfix.nix
./services/mail/spamassassin.nix
+ ./services/misc/apache-kafka.nix
#./services/misc/autofs.nix
+ ./services/misc/canto-daemon.nix
+ ./services/misc/cpuminer-cryptonight.nix
./services/misc/cgminer.nix
./services/misc/dictd.nix
./services/misc/disnix.nix
+ ./services/misc/docker-registry.nix
+ ./services/misc/etcd.nix
./services/misc/felix.nix
./services/misc/folding-at-home.nix
+ ./services/misc/gitlab.nix
./services/misc/gitolite.nix
./services/misc/gpsd.nix
+ ./services/misc/mediatomb.nix
+ ./services/misc/mesos-master.nix
+ ./services/misc/mesos-slave.nix
./services/misc/nix-daemon.nix
./services/misc/nix-gc.nix
./services/misc/nixos-manual.nix
./services/misc/nix-ssh-serve.nix
+ ./services/misc/parsoid.nix
+ ./services/misc/phd.nix
+ ./services/misc/redmine.nix
./services/misc/rippled.nix
+ ./services/misc/ripple-data-api.nix
./services/misc/rogue.nix
./services/misc/siproxd.nix
./services/misc/svnserve.nix
./services/misc/synergy.nix
+ ./services/misc/uhub.nix
./services/misc/zookeeper.nix
./services/monitoring/apcupsd.nix
+ ./services/monitoring/bosun.nix
+ ./services/monitoring/cadvisor.nix
+ ./services/monitoring/collectd.nix
./services/monitoring/dd-agent.nix
./services/monitoring/graphite.nix
./services/monitoring/monit.nix
@@ -177,9 +222,11 @@
./services/monitoring/nagios.nix
./services/monitoring/riemann.nix
./services/monitoring/riemann-dash.nix
+ ./services/monitoring/scollector.nix
./services/monitoring/smartd.nix
./services/monitoring/statsd.nix
./services/monitoring/systemhealth.nix
+ ./services/monitoring/teamviewer.nix
./services/monitoring/ups.nix
./services/monitoring/uptime.nix
./services/monitoring/zabbix-agent.nix
@@ -189,7 +236,12 @@
./services/network-filesystems/openafs-client/default.nix
./services/network-filesystems/rsyncd.nix
./services/network-filesystems/samba.nix
+ ./services/network-filesystems/diod.nix
+ ./services/network-filesystems/u9fs.nix
+ ./services/network-filesystems/yandex-disk.nix
+ ./services/networking/aiccu.nix
./services/networking/amuled.nix
+ ./services/networking/atftpd.nix
./services/networking/avahi-daemon.nix
./services/networking/bind.nix
./services/networking/bitlbee.nix
@@ -198,11 +250,14 @@
./services/networking/cjdns.nix
./services/networking/cntlm.nix
./services/networking/connman.nix
+ ./services/networking/consul.nix
./services/networking/ddclient.nix
./services/networking/dhcpcd.nix
./services/networking/dhcpd.nix
+ ./services/networking/dnscrypt-proxy.nix
./services/networking/dnsmasq.nix
./services/networking/ejabberd.nix
+ ./services/networking/firefox/sync-server.nix
./services/networking/firewall.nix
./services/networking/flashpolicyd.nix
./services/networking/freenet.nix
@@ -212,11 +267,14 @@
./services/networking/gvpe.nix
./services/networking/haproxy.nix
./services/networking/hostapd.nix
+ ./services/networking/i2pd.nix
./services/networking/ifplugd.nix
./services/networking/iodined.nix
./services/networking/ircd-hybrid/default.nix
./services/networking/kippo.nix
+ ./services/networking/mailpile.nix
./services/networking/minidlna.nix
+ ./services/networking/mstpd.nix
./services/networking/murmur.nix
./services/networking/nat.nix
./services/networking/networkmanager.nix
@@ -225,12 +283,15 @@
./services/networking/nsd.nix
./services/networking/ntopng.nix
./services/networking/ntpd.nix
+ ./services/networking/nylon.nix
./services/networking/oidentd.nix
./services/networking/openfire.nix
+ ./services/networking/openntpd.nix
./services/networking/openvpn.nix
./services/networking/polipo.nix
./services/networking/prayer.nix
./services/networking/privoxy.nix
+ ./services/networking/prosody.nix
./services/networking/quassel.nix
./services/networking/radicale.nix
./services/networking/radvd.nix
@@ -238,14 +299,20 @@
./services/networking/rpcbind.nix
./services/networking/sabnzbd.nix
./services/networking/searx.nix
+ ./services/networking/seeks.nix
./services/networking/spiped.nix
+ ./services/networking/sslh.nix
./services/networking/ssh/lshd.nix
./services/networking/ssh/sshd.nix
+ ./services/networking/strongswan.nix
./services/networking/supybot.nix
./services/networking/syncthing.nix
./services/networking/tcpcrypt.nix
./services/networking/teamspeak3.nix
+ ./services/networking/tinc.nix
./services/networking/tftpd.nix
+ ./services/networking/tlsdated.nix
+ ./services/networking/tox-bootstrapd.nix
./services/networking/unbound.nix
./services/networking/unifi.nix
./services/networking/vsftpd.nix
@@ -257,23 +324,29 @@
./services/networking/znc.nix
./services/printing/cupsd.nix
./services/scheduling/atd.nix
+ ./services/scheduling/chronos.nix
./services/scheduling/cron.nix
./services/scheduling/fcron.nix
+ ./services/scheduling/marathon.nix
./services/search/elasticsearch.nix
./services/search/solr.nix
./services/security/clamav.nix
./services/security/fail2ban.nix
+ ./services/security/fprintd.nix
./services/security/fprot.nix
./services/security/frandom.nix
./services/security/haveged.nix
+ ./services/security/munge.nix
./services/security/torify.nix
./services/security/tor.nix
./services/security/torsocks.nix
+ ./services/system/cloud-init.nix
./services/system/dbus.nix
./services/system/kerberos.nix
./services/system/nscd.nix
./services/system/uptimed.nix
./services/torrent/deluge.nix
+ ./services/torrent/peerflix.nix
./services/torrent/transmission.nix
./services/ttys/agetty.nix
./services/ttys/gpm.nix
@@ -287,15 +360,18 @@
./services/web-servers/nginx/default.nix
./services/web-servers/phpfpm.nix
./services/web-servers/tomcat.nix
+ ./services/web-servers/uwsgi.nix
./services/web-servers/varnish/default.nix
./services/web-servers/winstone.nix
./services/web-servers/zope2.nix
+ ./services/x11/unclutter.nix
./services/x11/desktop-managers/default.nix
./services/x11/display-managers/auto.nix
./services/x11/display-managers/default.nix
./services/x11/display-managers/gdm.nix
./services/x11/display-managers/kdm.nix
./services/x11/display-managers/lightdm.nix
+ ./services/x11/display-managers/sddm.nix
./services/x11/display-managers/slim.nix
./services/x11/hardware/multitouch.nix
./services/x11/hardware/synaptics.nix
@@ -320,8 +396,10 @@
./system/boot/kernel.nix
./system/boot/kexec.nix
./system/boot/loader/efi.nix
+ ./system/boot/loader/loader.nix
./system/boot/loader/generations-dir/generations-dir.nix
./system/boot/loader/grub/grub.nix
+ ./system/boot/loader/grub/ipxe.nix
./system/boot/loader/grub/memtest.nix
./system/boot/loader/gummiboot/gummiboot.nix
./system/boot/loader/init-script/init-script.nix
@@ -335,6 +413,7 @@
./system/boot/tmp.nix
./system/etc/etc.nix
./system/upstart/upstart.nix
+ ./tasks/bcache.nix
./tasks/cpu-freq.nix
./tasks/encrypted-devices.nix
./tasks/filesystems.nix
@@ -342,6 +421,7 @@
./tasks/filesystems/cifs.nix
./tasks/filesystems/ext.nix
./tasks/filesystems/f2fs.nix
+ ./tasks/filesystems/jfs.nix
./tasks/filesystems/nfs.nix
./tasks/filesystems/reiserfs.nix
./tasks/filesystems/unionfs-fuse.nix
@@ -351,6 +431,8 @@
./tasks/kbd.nix
./tasks/lvm.nix
./tasks/network-interfaces.nix
+ ./tasks/network-interfaces-systemd.nix
+ ./tasks/network-interfaces-scripted.nix
./tasks/scsi-link-power-management.nix
./tasks/swraid.nix
./tasks/trackpoint.nix
@@ -359,7 +441,10 @@
./virtualisation/containers.nix
./virtualisation/docker.nix
./virtualisation/libvirtd.nix
- #./virtualisation/nova.nix
+ ./virtualisation/lxc.nix
+ ./virtualisation/amazon-options.nix
+ ./virtualisation/openvswitch.nix
+ ./virtualisation/parallels-guest.nix
./virtualisation/virtualbox-guest.nix
- #./virtualisation/xen-dom0.nix
+ ./virtualisation/xen-dom0.nix
]
diff --git a/nixos/modules/profiles/base.nix b/nixos/modules/profiles/base.nix
index 6f9e3002f29..457642d82f7 100644
--- a/nixos/modules/profiles/base.nix
+++ b/nixos/modules/profiles/base.nix
@@ -10,6 +10,8 @@
pkgs.w3m # needed for the manual anyway
pkgs.testdisk # useful for repairing boot problems
pkgs.mssys # for writing Microsoft boot sectors / MBRs
+ pkgs.efibootmgr
+ pkgs.efivar
pkgs.parted
pkgs.gptfdisk
pkgs.ddrescue
@@ -34,10 +36,8 @@
pkgs.xfsprogs
pkgs.jfsutils
pkgs.f2fs-tools
- #pkgs.jfsrec # disabled because of Boost dependency
# Some compression/archiver tools.
- pkgs.unrar
pkgs.unzip
pkgs.zip
pkgs.dar # disk archiver
diff --git a/nixos/modules/profiles/container.nix b/nixos/modules/profiles/container.nix
new file mode 100644
index 00000000000..dd2e6579a93
--- /dev/null
+++ b/nixos/modules/profiles/container.nix
@@ -0,0 +1,56 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ pkgs2storeContents = l : map (x: { object = x; symlink = "none"; }) l;
+
+in {
+ # Docker image config.
+ imports = [
+ ../installer/cd-dvd/channel.nix
+ ./minimal.nix
+ ./clone-config.nix
+ ];
+
+ # Create the tarball
+ system.build.tarball = import ../../lib/make-system-tarball.nix {
+ inherit (pkgs) stdenv perl xz pathsFromGraph;
+
+ contents = [];
+ extraArgs = "--owner=0";
+
+ # Add init script to image
+ storeContents = [
+ { object = config.system.build.toplevel + "/init";
+ symlink = "/init";
+ }
+ ] ++ (pkgs2storeContents [ pkgs.stdenv ]);
+
+ # Some container managers like lxc need these
+ extraCommands = "mkdir -p proc sys dev";
+ };
+
+ boot.isContainer = true;
+ boot.postBootCommands =
+ ''
+ # After booting, register the contents of the Nix store in the Nix
+ # database.
+ if [ -f /nix-path-registration ]; then
+ ${config.nix.package}/bin/nix-store --load-db < /nix-path-registration &&
+ rm /nix-path-registration
+ fi
+
+ # nixos-rebuild also requires a "system" profile
+ ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
+ '';
+
+ # Disable some features that are not useful in a container.
+ sound.enable = mkDefault false;
+ services.udisks2.enable = mkDefault false;
+
+ # Install new init script
+ system.activationScripts.installInitScript = ''
+ ln -fs $systemConfig/init /init
+ '';
+}
diff --git a/nixos/modules/programs/bash/command-not-found.nix b/nixos/modules/programs/bash/command-not-found.nix
deleted file mode 100644
index 8c86d48b080..00000000000
--- a/nixos/modules/programs/bash/command-not-found.nix
+++ /dev/null
@@ -1,51 +0,0 @@
-# This module provides suggestions of packages to install if the user
-# tries to run a missing command in Bash. This is implemented using a
-# SQLite database that maps program names to Nix package names (e.g.,
-# "pdflatex" is mapped to "tetex").
-
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
- commandNotFound = pkgs.substituteAll {
- name = "command-not-found";
- dir = "bin";
- src = ./command-not-found.pl;
- isExecutable = true;
- inherit (pkgs) perl;
- perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
- [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]);
- };
-
-in
-
-{
-
- programs.bash.interactiveShellInit =
- ''
- # This function is called whenever a command is not found.
- command_not_found_handle() {
- local p=/run/current-system/sw/bin/command-not-found
- if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
- # Run the helper program.
- $p "$1"
- # Retry the command if we just installed it.
- if [ $? = 126 ]; then
- "$@"
- else
- return 127
- fi
- else
- echo "$1: command not found" >&2
- return 127
- fi
- }
- '';
-
- environment.systemPackages = [ commandNotFound ];
-
- # TODO: tab completion for uninstalled commands! :-)
-
-}
diff --git a/nixos/modules/programs/cdemu.nix b/nixos/modules/programs/cdemu.nix
new file mode 100644
index 00000000000..d1b1915eea9
--- /dev/null
+++ b/nixos/modules/programs/cdemu.nix
@@ -0,0 +1,49 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.programs.cdemu;
+in {
+
+ options = {
+ programs.cdemu = {
+ enable = mkOption {
+ default = false;
+ description = "Whether to enable cdemu for users of appropriate group (default cdrom)";
+ };
+ group = mkOption {
+ default = "cdrom";
+ description = "Required group for users of cdemu";
+ };
+ gui = mkOption {
+ default = true;
+ description = "Whether to install cdemu GUI (gCDEmu)";
+ };
+ image-analyzer = mkOption {
+ default = true;
+ description = "Whether to install image analyzer";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ boot = {
+ extraModulePackages = [ pkgs.linuxPackages.vhba ];
+ kernelModules = [ "vhba" ];
+ };
+
+ services = {
+ udev.extraRules = ''
+ KERNEL=="vhba_ctl", MODE="0660", OWNER="root", GROUP="${cfg.group}"
+ '';
+ dbus.packages = [ pkgs.cdemu-daemon ];
+ };
+
+ environment.systemPackages =
+ [ pkgs.cdemu-daemon pkgs.cdemu-client ]
+ ++ optional cfg.gui pkgs.gcdemu
+ ++ optional cfg.image-analyzer pkgs.image-analyzer;
+ };
+
+}
diff --git a/nixos/modules/programs/command-not-found/command-not-found.nix b/nixos/modules/programs/command-not-found/command-not-found.nix
new file mode 100644
index 00000000000..bead2dcdcf9
--- /dev/null
+++ b/nixos/modules/programs/command-not-found/command-not-found.nix
@@ -0,0 +1,71 @@
+# This module provides suggestions of packages to install if the user
+# tries to run a missing command in Bash. This is implemented using a
+# SQLite database that maps program names to Nix package names (e.g.,
+# "pdflatex" is mapped to "tetex").
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ commandNotFound = pkgs.substituteAll {
+ name = "command-not-found";
+ dir = "bin";
+ src = ./command-not-found.pl;
+ isExecutable = true;
+ inherit (pkgs) perl;
+ perlFlags = concatStrings (map (path: "-I ${path}/lib/perl5/site_perl ")
+ [ pkgs.perlPackages.DBI pkgs.perlPackages.DBDSQLite ]);
+ };
+
+in
+
+{
+
+ programs.bash.interactiveShellInit =
+ ''
+ # This function is called whenever a command is not found.
+ command_not_found_handle() {
+ local p=/run/current-system/sw/bin/command-not-found
+ if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
+ # Run the helper program.
+ $p "$1"
+ # Retry the command if we just installed it.
+ if [ $? = 126 ]; then
+ "$@"
+ else
+ return 127
+ fi
+ else
+ echo "$1: command not found" >&2
+ return 127
+ fi
+ }
+ '';
+
+ programs.zsh.interactiveShellInit =
+ ''
+ # This function is called whenever a command is not found.
+ command_not_found_handler() {
+ local p=/run/current-system/sw/bin/command-not-found
+ if [ -x $p -a -f /nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite ]; then
+ # Run the helper program.
+ $p "$1"
+
+ # Retry the command if we just installed it.
+ if [ $? = 126 ]; then
+ "$@"
+ fi
+ else
+ # Indicate than there was an error so ZSH falls back to its default handler
+ return 127
+ fi
+ }
+ '';
+
+ environment.systemPackages = [ commandNotFound ];
+
+ # TODO: tab completion for uninstalled commands! :-)
+
+}
diff --git a/nixos/modules/programs/bash/command-not-found.pl b/nixos/modules/programs/command-not-found/command-not-found.pl
similarity index 100%
rename from nixos/modules/programs/bash/command-not-found.pl
rename to nixos/modules/programs/command-not-found/command-not-found.pl
diff --git a/nixos/modules/programs/environment.nix b/nixos/modules/programs/environment.nix
index 4a510805b01..e0379a2c02a 100644
--- a/nixos/modules/programs/environment.nix
+++ b/nixos/modules/programs/environment.nix
@@ -37,26 +37,25 @@ in
"/run/current-system/sw"
];
- # !!! fix environment.profileVariables definition and then move
- # most of these elsewhere
- environment.profileVariables = (i:
- { PATH = [ "${i}/bin" "${i}/sbin" "${i}/lib/kde4/libexec" ];
- MANPATH = [ "${i}/man" "${i}/share/man" ];
- INFOPATH = [ "${i}/info" "${i}/share/info" ];
- PKG_CONFIG_PATH = [ "${i}/lib/pkgconfig" ];
- TERMINFO_DIRS = [ "${i}/share/terminfo" ];
- PERL5LIB = [ "${i}/lib/perl5/site_perl" ];
- ALSA_PLUGIN_DIRS = [ "${i}/lib/alsa-lib" ];
- GST_PLUGIN_SYSTEM_PATH = [ "${i}/lib/gstreamer-0.10" ];
- KDEDIRS = [ "${i}" ];
- STRIGI_PLUGIN_PATH = [ "${i}/lib/strigi/" ];
- QT_PLUGIN_PATH = [ "${i}/lib/qt4/plugins" "${i}/lib/kde4/plugins" ];
- QTWEBKIT_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins/" ];
- GTK_PATH = [ "${i}/lib/gtk-2.0" "${i}/lib/gtk-3.0" ];
- XDG_CONFIG_DIRS = [ "${i}/etc/xdg" ];
- XDG_DATA_DIRS = [ "${i}/share" ];
- MOZ_PLUGIN_PATH = [ "${i}/lib/mozilla/plugins" ];
- });
+ # TODO: move most of these elsewhere
+ environment.profileRelativeEnvVars =
+ { PATH = [ "/bin" "/sbin" "/lib/kde4/libexec" ];
+ INFOPATH = [ "/info" "/share/info" ];
+ PKG_CONFIG_PATH = [ "/lib/pkgconfig" ];
+ TERMINFO_DIRS = [ "/share/terminfo" ];
+ PERL5LIB = [ "/lib/perl5/site_perl" ];
+ KDEDIRS = [ "" ];
+ STRIGI_PLUGIN_PATH = [ "/lib/strigi/" ];
+ QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" "/lib/qt5/plugins" ];
+ QML_IMPORT_PATH = [ "/lib/qt5/imports" ];
+ QML2_IMPORT_PATH = [ "/lib/qt5/qml" ];
+ QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
+ GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
+ XDG_CONFIG_DIRS = [ "/etc/xdg" ];
+ XDG_DATA_DIRS = [ "/share" ];
+ MOZ_PLUGIN_PATH = [ "/lib/mozilla/plugins" ];
+ LIBEXEC_PATH = [ "/lib/libexec" ];
+ };
environment.extraInit =
''
diff --git a/nixos/modules/programs/ibus.nix b/nixos/modules/programs/ibus.nix
new file mode 100644
index 00000000000..b8702a743d8
--- /dev/null
+++ b/nixos/modules/programs/ibus.nix
@@ -0,0 +1,51 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.programs.ibus;
+in
+{
+ options = {
+
+ programs.ibus = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Enable IBus input method";
+ };
+ plugins = mkOption {
+ type = lib.types.listOf lib.types.path;
+ default = [];
+ description = ''
+ IBus plugin packages
+ '';
+ };
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.ibus ];
+
+ gtkPlugins = [ pkgs.ibus ];
+ qtPlugins = [ pkgs.ibus-qt ];
+
+ environment.variables =
+ let
+ env = pkgs.buildEnv {
+ name = "ibus-env";
+ paths = [ pkgs.ibus ] ++ cfg.plugins;
+ };
+ in {
+ GTK_IM_MODULE = "ibus";
+ QT_IM_MODULE = "ibus";
+ XMODIFIERS = "@im=ibus";
+
+ IBUS_COMPONENT_PATH = "${env}/share/ibus/component";
+ };
+
+ services.xserver.displayManager.sessionCommands = "${pkgs.ibus}/bin/ibus-daemon --daemonize --xim --cache=none";
+ };
+}
diff --git a/nixos/modules/programs/light.nix b/nixos/modules/programs/light.nix
new file mode 100644
index 00000000000..09cd1113d9c
--- /dev/null
+++ b/nixos/modules/programs/light.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.programs.light;
+
+in
+{
+ options = {
+ programs.light = {
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to install Light backlight control with setuid wrapper.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.light ];
+ security.setuidPrograms = [ "light" ];
+ };
+}
diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix
index 5a467e112c2..895ecb122cb 100644
--- a/nixos/modules/programs/shadow.nix
+++ b/nixos/modules/programs/shadow.nix
@@ -83,7 +83,7 @@ in
security.pam.services =
{ chsh = { rootOK = true; };
chfn = { rootOK = true; };
- su = { rootOK = true; forwardXAuth = true; };
+ su = { rootOK = true; forwardXAuth = true; logFailures = true; };
passwd = {};
# Note: useradd, groupadd etc. aren't setuid root, so it
# doesn't really matter what the PAM config says as long as it
@@ -100,7 +100,7 @@ in
chgpasswd = { rootOK = true; };
};
- security.setuidPrograms = [ "passwd" "chfn" "su" "newgrp"
+ security.setuidPrograms = [ "passwd" "chfn" "su" "sg" "newgrp"
"newuidmap" "newgidmap" # new in shadow 4.2.x
];
diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix
index fdb9dfd4b8c..6ca73eea5f6 100644
--- a/nixos/modules/programs/ssh.nix
+++ b/nixos/modules/programs/ssh.nix
@@ -4,8 +4,19 @@
with lib;
-let cfg = config.programs.ssh;
- cfgd = config.services.openssh;
+let
+
+ cfg = config.programs.ssh;
+ cfgd = config.services.openssh;
+
+ askPassword = cfg.askPassword;
+
+ askPasswordWrapper = pkgs.writeScript "ssh-askpass-wrapper"
+ ''
+ #! ${pkgs.stdenv.shell} -e
+ export DISPLAY="$(systemctl --user show-environment | ${pkgs.gnused}/bin/sed 's/^DISPLAY=\(.*\)/\1/; t; d')"
+ exec ${askPassword}
+ '';
in
{
@@ -15,6 +26,12 @@ in
programs.ssh = {
+ askPassword = mkOption {
+ type = types.string;
+ default = "${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass";
+ description = ''Program used by SSH to ask for passwords.'';
+ };
+
forwardX11 = mkOption {
type = types.bool;
default = false;
@@ -59,6 +76,22 @@ in
'';
};
+ agentTimeout = mkOption {
+ type = types.nullOr types.string;
+ default = null;
+ example = "1h";
+ description = ''
+ How long to keep the private keys in memory. Use null to keep them forever.
+ '';
+ };
+
+ package = mkOption {
+ default = pkgs.openssh;
+ description = ''
+ The package used for the openssh client and daemon.
+ '';
+ };
+
};
};
@@ -92,12 +125,20 @@ in
wantedBy = [ "default.target" ];
serviceConfig =
{ ExecStartPre = "${pkgs.coreutils}/bin/rm -f %t/ssh-agent";
- ExecStart = "${pkgs.openssh}/bin/ssh-agent -a %t/ssh-agent";
+ ExecStart =
+ "${cfg.package}/bin/ssh-agent " +
+ optionalString (cfg.agentTimeout != null) ("-t ${cfg.agentTimeout} ") +
+ "-a %t/ssh-agent";
StandardOutput = "null";
Type = "forking";
Restart = "on-failure";
SuccessExitStatus = "0 2";
};
+ # Allow ssh-agent to ask for confirmation. This requires the
+ # unit to know about the user's $DISPLAY (via ‘systemctl
+ # import-environment’).
+ environment.SSH_ASKPASS = optionalString config.services.xserver.enable askPasswordWrapper;
+ environment.DISPLAY = "fake"; # required to make ssh-agent start $SSH_ASKPASS
};
environment.extraInit = optionalString cfg.startAgent
@@ -107,5 +148,10 @@ in
fi
'';
+ environment.interactiveShellInit = optionalString config.services.xserver.enable
+ ''
+ export SSH_ASKPASS=${askPassword}
+ '';
+
};
}
diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix
index 34eafd4fa84..7b00efbb468 100644
--- a/nixos/modules/programs/ssmtp.nix
+++ b/nixos/modules/programs/ssmtp.nix
@@ -20,6 +20,7 @@ in
networking.defaultMailServer = {
directDelivery = mkOption {
+ type = types.bool;
default = false;
example = true;
description = ''
@@ -35,6 +36,7 @@ in
};
hostName = mkOption {
+ type = types.str;
example = "mail.example.org";
description = ''
The host name of the default mail server to use to deliver
@@ -42,7 +44,17 @@ in
'';
};
+ root = mkOption {
+ type = types.str;
+ default = "";
+ example = "root@example.org";
+ description = ''
+ The e-mail to which mail for users with UID < 1000 is forwarded.
+ '';
+ };
+
domain = mkOption {
+ type = types.str;
default = "";
example = "example.org";
description = ''
@@ -51,6 +63,7 @@ in
};
useTLS = mkOption {
+ type = types.bool;
default = false;
example = true;
description = ''
@@ -60,6 +73,7 @@ in
};
useSTARTTLS = mkOption {
+ type = types.bool;
default = false;
example = true;
description = ''
@@ -70,6 +84,7 @@ in
};
authUser = mkOption {
+ type = types.str;
default = "";
example = "foo@example.org";
description = ''
@@ -78,6 +93,7 @@ in
};
authPass = mkOption {
+ type = types.str;
default = "";
example = "correctHorseBatteryStaple";
description = ''
@@ -96,6 +112,7 @@ in
''
MailHub=${cfg.hostName}
FromLineOverride=YES
+ ${if cfg.root != "" then "root=${cfg.root}" else ""}
${if cfg.domain != "" then "rewriteDomain=${cfg.domain}" else ""}
UseTLS=${if cfg.useTLS then "YES" else "NO"}
UseSTARTTLS=${if cfg.useSTARTTLS then "YES" else "NO"}
diff --git a/nixos/modules/programs/uim.nix b/nixos/modules/programs/uim.nix
index 237da3415dc..4bf2f9a1757 100644
--- a/nixos/modules/programs/uim.nix
+++ b/nixos/modules/programs/uim.nix
@@ -1,20 +1,22 @@
-{ config, pkgs, ... }:
+{ config, pkgs, lib, ... }:
-with pkgs.lib;
+with lib;
let
cfg = config.uim;
in
{
options = {
+
uim = {
enable = mkOption {
type = types.bool;
default = false;
example = true;
- description = "enable UIM input method";
+ description = "Enable UIM input method";
};
};
+
};
config = mkIf cfg.enable {
diff --git a/nixos/modules/programs/virtualbox-host.nix b/nixos/modules/programs/virtualbox-host.nix
new file mode 100644
index 00000000000..fc113a08a35
--- /dev/null
+++ b/nixos/modules/programs/virtualbox-host.nix
@@ -0,0 +1,115 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.virtualboxHost;
+ virtualbox = config.boot.kernelPackages.virtualbox.override {
+ inherit (cfg) enableHardening;
+ };
+
+in
+
+{
+ options.services.virtualboxHost = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable host-side support for VirtualBox.
+
+
+ In order to pass USB devices from the host to the guests, the user
+ needs to be in the vboxusers group.
+
+ '';
+ };
+
+ addNetworkInterface = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Automatically set up a vboxnet0 host-only network interface.
+ '';
+ };
+
+ enableHardening = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Enable hardened VirtualBox, which ensures that only the binaries in the
+ system path get access to the devices exposed by the kernel modules
+ instead of all users in the vboxusers group.
+
+
+ Disabling this can put your system's security at risk, as local users
+ in the vboxusers group can tamper with the VirtualBox device files.
+
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable (mkMerge [{
+ boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
+ boot.extraModulePackages = [ virtualbox ];
+ environment.systemPackages = [ virtualbox ];
+
+ security.setuidOwners = let
+ mkSuid = program: {
+ inherit program;
+ source = "${virtualbox}/libexec/virtualbox/${program}";
+ owner = "root";
+ group = "vboxusers";
+ setuid = true;
+ };
+ in mkIf cfg.enableHardening (map mkSuid [
+ "VBoxHeadless"
+ "VBoxNetAdpCtl"
+ "VBoxNetDHCP"
+ "VBoxNetNAT"
+ "VBoxSDL"
+ "VBoxVolInfo"
+ "VirtualBox"
+ ]);
+
+ users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers;
+
+ services.udev.extraRules =
+ ''
+ KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
+ KERNEL=="vboxdrvu", OWNER="root", GROUP="root", MODE="0666", TAG+="systemd"
+ KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
+ SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+ SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
+ SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
+ SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
+ '';
+
+ # Since we lack the right setuid binaries, set up a host-only network by default.
+ } (mkIf cfg.addNetworkInterface {
+ systemd.services."vboxnet0" =
+ { description = "VirtualBox vboxnet0 Interface";
+ requires = [ "dev-vboxnetctl.device" ];
+ after = [ "dev-vboxnetctl.device" ];
+ wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ];
+ path = [ virtualbox ];
+ serviceConfig.RemainAfterExit = true;
+ serviceConfig.Type = "oneshot";
+ serviceConfig.PrivateTmp = true;
+ environment.VBOX_USER_HOME = "/tmp";
+ script =
+ ''
+ if ! [ -e /sys/class/net/vboxnet0 ]; then
+ VBoxManage hostonlyif create
+ cat /tmp/VBoxSVC.log >&2
+ fi
+ '';
+ postStop =
+ ''
+ VBoxManage hostonlyif remove vboxnet0
+ '';
+ };
+
+ networking.interfaces.vboxnet0.ip4 = [ { address = "192.168.56.1"; prefixLength = 24; } ];
+ })]);
+}
diff --git a/nixos/modules/programs/virtualbox.nix b/nixos/modules/programs/virtualbox.nix
index e2dd76219eb..a00b1e5f64d 100644
--- a/nixos/modules/programs/virtualbox.nix
+++ b/nixos/modules/programs/virtualbox.nix
@@ -1,48 +1,8 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let virtualbox = config.boot.kernelPackages.virtualbox; in
-
-{
- boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
- boot.extraModulePackages = [ virtualbox ];
- environment.systemPackages = [ virtualbox ];
-
- users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers;
-
- services.udev.extraRules =
- ''
- KERNEL=="vboxdrv", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
- KERNEL=="vboxdrvu", OWNER="root", GROUP="root", MODE="0666", TAG+="systemd"
- KERNEL=="vboxnetctl", OWNER="root", GROUP="root", MODE="0600", TAG+="systemd"
- SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
- SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
- SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
- SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
- '';
-
- # Since we lack the right setuid binaries, set up a host-only network by default.
-
- systemd.services."vboxnet0" =
- { description = "VirtualBox vboxnet0 Interface";
- requires = [ "dev-vboxnetctl.device" ];
- after = [ "dev-vboxnetctl.device" ];
- wantedBy = [ "network.target" "sys-subsystem-net-devices-vboxnet0.device" ];
- path = [ virtualbox ];
- serviceConfig.RemainAfterExit = true;
- serviceConfig.Type = "oneshot";
- script =
- ''
- if ! [ -e /sys/class/net/vboxnet0 ]; then
- VBoxManage hostonlyif create
- fi
- '';
- postStop =
- ''
- VBoxManage hostonlyif remove vboxnet0
- '';
- };
-
- networking.interfaces.vboxnet0 = { ipAddress = "192.168.56.1"; prefixLength = 24; };
+let
+ msg = "Importing is "
+ + "deprecated, please use `services.virtualboxHost.enable = true' "
+ + "instead.";
+in {
+ config.warnings = [ msg ];
+ config.services.virtualboxHost.enable = true;
}
diff --git a/nixos/modules/programs/zsh/zsh.nix b/nixos/modules/programs/zsh/zsh.nix
index 1857371ebe8..74dd6af0bdd 100644
--- a/nixos/modules/programs/zsh/zsh.nix
+++ b/nixos/modules/programs/zsh/zsh.nix
@@ -100,7 +100,7 @@ in
export HISTSIZE=2000
export HISTFILE=$HOME/.zsh_history
- setopt HIST_IGNORE_DUPS SHARE_HISTORY
+ setopt HIST_IGNORE_DUPS SHARE_HISTORY HIST_FCNTL_LOCK
'';
};
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 0ee2caa28ea..d90cffbd967 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -33,7 +33,8 @@ let
zipModules = list:
zipAttrsWith (n: v:
if tail v != [] then
- if n == "_type" then (head v)
+ if all (o: isAttrs o && o ? _type) v then mkMerge v
+ else if n == "_type" then head v
else if n == "warnings" then concatLists v
else if n == "description" || n == "apply" then
abort "Cannot rename an option to multiple options."
@@ -55,8 +56,8 @@ let
apply = x: use (toOf config);
inherit visible;
});
- }
- { config = setTo (mkMerge (if (fromOf options).isDefined then [ (define (mkMerge (fromOf options).definitions)) ] else []));
+
+ config = setTo (mkAliasAndWrapDefinitions define (fromOf options));
}
];
@@ -74,6 +75,7 @@ in zipModules ([]
++ obsolete [ "environment" "x11Packages" ] [ "environment" "systemPackages" ]
++ obsolete [ "environment" "enableBashCompletion" ] [ "programs" "bash" "enableCompletion" ]
++ obsolete [ "environment" "nix" ] [ "nix" "package" ]
+++ obsolete [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ]
++ obsolete [ "fonts" "extraFonts" ] [ "fonts" "fonts" ]
++ obsolete [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ]
@@ -105,11 +107,19 @@ in zipModules ([]
++ obsolete [ "services" "sshd" "permitRootLogin" ] [ "services" "openssh" "permitRootLogin" ]
++ obsolete [ "services" "xserver" "startSSHAgent" ] [ "services" "xserver" "startOpenSSHAgent" ]
++ obsolete [ "services" "xserver" "startOpenSSHAgent" ] [ "programs" "ssh" "startAgent" ]
-++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "xbmc" ]
+
+# VirtualBox
+++ obsolete [ "services" "virtualbox" "enable" ] [ "services" "virtualboxGuest" "enable" ]
+
+# Tarsnap
+++ obsolete [ "services" "tarsnap" "config" ] [ "services" "tarsnap" "archives" ]
+
+# proxy
+++ obsolete [ "nix" "proxy" ] [ "networking" "proxy" "default" ]
# KDE
-++ deprecated [ "kde" "extraPackages" ] [ "environment" "kdePackages" ]
-# ++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ] # !!! doesn't work!
+++ deprecated [ "kde" "extraPackages" ] [ "environment" "systemPackages" ]
+++ obsolete [ "environment" "kdePackages" ] [ "environment" "systemPackages" ]
# Multiple efi bootloaders now
++ obsolete [ "boot" "loader" "efi" "efibootmgr" "enable" ] [ "boot" "loader" "efi" "canTouchEfiVariables" ]
@@ -125,9 +135,18 @@ in zipModules ([]
++ obsolete [ "services" "mysql55" ] [ "services" "mysql" ]
+++ obsolete [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]
+
+# XBMC
+++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
+++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
+
# Options that are obsolete and have no replacement.
++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
++ obsolete' [ "boot" "initrd" "luks" "enable" ]
++ obsolete' [ "programs" "bash" "enable" ]
+++ obsolete' [ "services" "samba" "defaultShare" ]
+++ obsolete' [ "services" "syslog-ng" "serviceName" ]
+++ obsolete' [ "services" "syslog-ng" "listenToJournal" ]
)
diff --git a/nixos/modules/security/apparmor.nix b/nixos/modules/security/apparmor.nix
index f29e7a5ad81..4fef62cbffd 100644
--- a/nixos/modules/security/apparmor.nix
+++ b/nixos/modules/security/apparmor.nix
@@ -1,43 +1,49 @@
{ config, lib, pkgs, ... }:
-with lib;
-
let
+ inherit (lib) mkIf mkOption types concatMapStrings;
cfg = config.security.apparmor;
in
+
{
- options = {
- security.apparmor = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = "Enable the AppArmor Mandatory Access Control system.";
- };
+ options = {
+ security.apparmor = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable the AppArmor Mandatory Access Control system.";
+ };
+ profiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = "List of files containing AppArmor profiles.";
+ };
+ };
+ };
- profiles = mkOption {
- type = types.listOf types.path;
- default = [];
- description = "List of files containing AppArmor profiles.";
- };
- };
- };
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.apparmor-utils ];
- config = mkIf cfg.enable {
- environment.systemPackages = [ pkgs.apparmor ];
- systemd.services.apparmor = {
- wantedBy = [ "local-fs.target" ];
- path = [ pkgs.apparmor ];
+ systemd.services.apparmor = {
+ wantedBy = [ "local-fs.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = "yes";
+ ExecStart = concatMapStrings (p:
+ ''${pkgs.apparmor-parser}/bin/apparmor_parser -rKv -I ${pkgs.apparmor-profiles}/etc/apparmor.d "${p}" ; ''
+ ) cfg.profiles;
+ ExecStop = concatMapStrings (p:
+ ''${pkgs.apparmor-parser}/bin/apparmor_parser -Rv "${p}" ; ''
+ ) cfg.profiles;
+ };
+ };
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = "yes";
- ExecStart = concatMapStrings (profile:
- ''${pkgs.apparmor}/sbin/apparmor_parser -rKv -I ${pkgs.apparmor}/etc/apparmor.d/ "${profile}" ; ''
- ) cfg.profiles;
- ExecStop = concatMapStrings (profile:
- ''${pkgs.apparmor}/sbin/apparmor_parser -Rv -I ${pkgs.apparmor}/etc/apparmor.d/ "${profile}" ; ''
- ) cfg.profiles;
- };
- };
- };
+ security.pam.services.apparmor.text = ''
+ ## AppArmor changes hats according to `order`: first try user, then
+ ## group, and finally fall back to a hat called "DEFAULT"
+ ##
+ ## For now, enable debugging as this is an experimental feature.
+ session optional ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so order=user,group,default debug
+ '';
+ };
}
diff --git a/nixos/modules/security/ca.nix b/nixos/modules/security/ca.nix
index 8e653cd4284..e60cb5cdb67 100644
--- a/nixos/modules/security/ca.nix
+++ b/nixos/modules/security/ca.nix
@@ -2,21 +2,74 @@
with lib;
+let
+
+ caBundle = pkgs.runCommand "ca-bundle.crt"
+ { files =
+ config.security.pki.certificateFiles ++
+ [ (builtins.toFile "extra.crt" (concatStringsSep "\n" config.security.pki.certificates)) ];
+ }
+ ''
+ cat $files > $out
+ '';
+
+in
+
{
+ options = {
+
+ security.pki.certificateFiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ example = literalExample "[ \"\${pkgs.cacert}/etc/ca-bundle.crt\" ]";
+ description = ''
+ A list of files containing trusted root certificates in PEM
+ format. These are concatenated to form
+ /etc/ssl/certs/ca-bundle.crt , which is
+ used by many programs that use OpenSSL, such as
+ curl and git .
+ '';
+ };
+
+ security.pki.certificates = mkOption {
+ type = types.listOf types.string;
+ default = [];
+ example = singleton ''
+ NixOS.org
+ =========
+ -----BEGIN CERTIFICATE-----
+ MIIGUDCCBTigAwIBAgIDD8KWMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
+ TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
+ ...
+ -----END CERTIFICATE-----
+ '';
+ description = ''
+ A list of trusted root certificates in PEM format.
+ '';
+ };
+
+ };
+
config = {
- environment.etc =
- [ { source = "${pkgs.cacert}/etc/ca-bundle.crt";
- target = "ssl/certs/ca-bundle.crt";
- }
- ];
+ security.pki.certificateFiles = [ "${pkgs.cacert}/etc/ca-bundle.crt" ];
+
+ # NixOS canonical location + Debian/Ubuntu/Arch/Gentoo compatibility.
+ environment.etc."ssl/certs/ca-certificates.crt".source = caBundle;
+
+ # Old NixOS compatibility.
+ environment.etc."ssl/certs/ca-bundle.crt".source = caBundle;
+
+ # CentOS/Fedora compatibility.
+ environment.etc."pki/tls/certs/ca-bundle.crt".source = caBundle;
environment.sessionVariables =
- { SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
+ { SSL_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
# FIXME: unneeded - remove eventually.
- OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
- GIT_SSL_CAINFO = "/etc/ssl/certs/ca-bundle.crt";
+ OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-certificates.crt";
+ # FIXME: unneeded - remove eventually.
+ GIT_SSL_CAINFO = "/etc/ssl/certs/ca-certificates.crt";
};
};
diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix
index 9893e63fb24..0e3a54325ca 100644
--- a/nixos/modules/security/duosec.nix
+++ b/nixos/modules/security/duosec.nix
@@ -110,7 +110,7 @@ in
default = false;
description = ''
Print the contents of /etc/motd to screen
- after a succesful login.
+ after a successful login.
'';
};
@@ -145,7 +145,7 @@ in
When $DUO_PASSCODE is non-empty, it will override
autopush. The SSH client will need SendEnv DUO_PASSCODE in
- its configuration, and the SSH server will similarily need
+ its configuration, and the SSH server will similarly need
AcceptEnv DUO_PASSCODE.
'';
};
diff --git a/nixos/modules/security/grsecurity.nix b/nixos/modules/security/grsecurity.nix
index 9e598369137..35974f6890e 100644
--- a/nixos/modules/security/grsecurity.nix
+++ b/nixos/modules/security/grsecurity.nix
@@ -30,7 +30,7 @@ in
type = types.bool;
default = false;
description = ''
- Enable the stable grsecurity patch, based on Linux 3.2.
+ Enable the stable grsecurity patch, based on Linux 3.14.
'';
};
@@ -38,59 +38,47 @@ in
type = types.bool;
default = false;
description = ''
- Enable the testing grsecurity patch, based on Linux 3.13.
+ Enable the testing grsecurity patch, based on Linux 3.19.
'';
};
config = {
mode = mkOption {
- type = types.str;
+ type = types.enum [ "auto" "custom" ];
default = "auto";
- example = "custom";
description = ''
grsecurity configuration mode. This specifies whether
grsecurity is auto-configured or otherwise completely
- manually configured. Can either be
- custom or auto .
-
- auto is recommended.
+ manually configured.
'';
};
priority = mkOption {
- type = types.str;
+ type = types.enum [ "security" "performance" ];
default = "security";
- example = "performance";
description = ''
grsecurity configuration priority. This specifies whether
the kernel configuration should emphasize speed or
- security. Can either be security or
- performance .
+ security.
'';
};
system = mkOption {
- type = types.str;
- default = "";
- example = "desktop";
+ type = types.enum [ "desktop" "server" ];
+ default = "desktop";
description = ''
- grsecurity system configuration. This specifies whether
- the kernel configuration should be suitable for a Desktop
- or a Server. Can either be server or
- desktop .
+ grsecurity system configuration.
'';
};
virtualisationConfig = mkOption {
- type = types.str;
- default = "none";
- example = "host";
+ type = types.nullOr (types.enum [ "host" "guest" ]);
+ default = null;
description = ''
grsecurity virtualisation configuration. This specifies
the virtualisation role of the machine - that is, whether
it will be a virtual machine guest, a virtual machine
- host, or neither. Can be one of none ,
- host , or guest .
+ host, or neither.
'';
};
@@ -106,17 +94,10 @@ in
};
virtualisationSoftware = mkOption {
- type = types.str;
- default = "";
- example = "kvm";
+ type = types.nullOr (types.enum [ "kvm" "xen" "vmware" "virtualbox" ]);
+ default = null;
description = ''
- grsecurity virtualisation software. Set this to the
- specified virtual machine technology if the machine is
- running as a guest, or a host.
-
- Can be one of kvm ,
- xen , vmware or
- virtualbox .
+ Configure grsecurity for use with this virtualisation software.
'';
};
@@ -156,6 +137,24 @@ in
'';
};
+ denyUSB = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If true, then set GRKERNSEC_DENYUSB y .
+
+ This enables a sysctl with name
+ kernel.grsecurity.deny_new_usb . Setting
+ its value to 1 will prevent any new USB
+ devices from being recognized by the OS. Any attempted
+ USB device insertion will be logged.
+
+ This option is intended to be used against custom USB
+ devices designed to exploit vulnerabilities in various USB
+ device drivers.
+ '';
+ };
+
restrictProc = mkOption {
type = types.bool;
default = false;
@@ -226,8 +225,8 @@ in
[ { assertion = cfg.stable || cfg.testing;
message = ''
If grsecurity is enabled, you must select either the
- stable patch (with kernel 3.2), or the testing patch (with
- kernel 3.13) to continue.
+ stable patch (with kernel 3.14), or the testing patch (with
+ kernel 3.19) to continue.
'';
}
{ assertion = (cfg.stable -> !cfg.testing) || (cfg.testing -> !cfg.stable);
@@ -244,34 +243,23 @@ in
&& config.boot.kernelPackages.kernel.features.grsecurity;
message = "grsecurity enabled, but kernel doesn't have grsec support";
}
- { assertion = elem cfg.config.mode [ "auto" "custom" ];
- message = "grsecurity mode must either be 'auto' or 'custom'.";
- }
- { assertion = cfg.config.mode == "auto" -> elem cfg.config.system [ "desktop" "server" ];
- message = "when using auto grsec mode, system must be either 'desktop' or 'server'";
- }
- { assertion = cfg.config.mode == "auto" -> elem cfg.config.priority [ "performance" "security" ];
- message = "when using auto grsec mode, priority must be 'performance' or 'security'.";
- }
- { assertion = cfg.config.mode == "auto" -> elem cfg.config.virtualisationConfig [ "host" "guest" "none" ];
- message = "when using auto grsec mode, 'virt' must be 'host', 'guest' or 'none'.";
- }
- { assertion = (cfg.config.mode == "auto" && (elem cfg.config.virtualisationConfig [ "host" "guest" ])) ->
+ { assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
cfg.config.hardwareVirtualisation != null;
message = "when using auto grsec mode with virtualisation, you must specify if your hardware has virtualisation extensions";
}
- { assertion = (cfg.config.mode == "auto" && (elem cfg.config.virtualisationConfig [ "host" "guest" ])) ->
- elem cfg.config.virtualisationSoftware [ "kvm" "xen" "virtualbox" "vmware" ];
- message = "virtualisation software must be 'kvm', 'xen', 'vmware' or 'virtualbox'";
+ { assertion = (cfg.config.mode == "auto" && (cfg.config.virtualisationConfig != null)) ->
+ cfg.config.virtualisationSoftware != null;
+ message = "grsecurity configured for virtualisation but no virtualisation software specified";
}
];
systemd.services.grsec-lock = mkIf cfg.config.sysctl {
description = "grsecurity sysctl-lock Service";
- requires = [ "sysctl.service" ];
+ requires = [ "systemd-sysctl.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = "yes";
+ unitConfig.ConditionPathIsReadWrite = "/proc/sys/kernel/grsecurity/grsec_lock";
script = ''
locked=`cat /proc/sys/kernel/grsecurity/grsec_lock`
if [ "$locked" == "0" ]; then
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index b1b75a0068d..631e8317cb4 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -6,8 +6,9 @@
with lib;
let
+ parentConfig = config;
- pamOpts = args: {
+ pamOpts = { config, name, ... }: let cfg = config; in let config = parentConfig; in {
options = {
@@ -54,6 +55,23 @@ let
'';
};
+ fprintAuth = mkOption {
+ default = config.services.fprintd.enable;
+ type = types.bool;
+ description = ''
+ If set, fingerprint reader will be used (if exists and
+ your fingerprints are enrolled).
+ '';
+ };
+
+ oathAuth = mkOption {
+ default = config.security.pam.enableOATH;
+ type = types.bool;
+ description = ''
+ If set, the OATH Toolkit will be used.
+ '';
+ };
+
sshAgentAuth = mkOption {
default = false;
type = types.bool;
@@ -113,6 +131,14 @@ let
'';
};
+ requireWheel = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to permit root access only to members of group wheel.
+ '';
+ };
+
limits = mkOption {
description = ''
Attribute set describing resource limits. Defaults to the
@@ -126,12 +152,28 @@ let
description = "Whether to show the message of the day.";
};
+ makeHomeDir = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to try to create home directories for users
+ with $HOME s pointing to nonexistent
+ locations on session login.
+ '';
+ };
+
updateWtmp = mkOption {
default = false;
type = types.bool;
description = "Whether to update /var/log/wtmp .";
};
+ logFailures = mkOption {
+ default = false;
+ type = types.bool;
+ description = "Whether to log authentication failures in /var/log/faillog .";
+ };
+
text = mkOption {
type = types.nullOr types.lines;
description = "Contents of the PAM service file.";
@@ -139,8 +181,8 @@ let
};
- config = let cfg = args.config; in {
- name = mkDefault args.name;
+ config = {
+ name = mkDefault name;
setLoginUid = mkDefault cfg.startSession;
limits = mkDefault config.security.pam.loginLimits;
@@ -159,14 +201,24 @@ let
# Authentication management.
${optionalString cfg.rootOK
"auth sufficient pam_rootok.so"}
+ ${optionalString cfg.requireWheel
+ "auth required pam_wheel.so use_uid"}
+ ${optionalString cfg.logFailures
+ "auth required pam_tally.so"}
${optionalString (config.security.pam.enableSSHAgentAuth && cfg.sshAgentAuth)
"auth sufficient ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys:~/.ssh/authorized_keys2:/etc/ssh/authorized_keys.d/%u"}
+ ${optionalString cfg.fprintAuth
+ "auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so"}
${optionalString cfg.usbAuth
"auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so"}
${optionalString cfg.unixAuth
- "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth"}
+ "auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth"}
+ ${optionalString config.security.pam.enableEcryptfs
+ "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
${optionalString cfg.otpwAuth
"auth sufficient ${pkgs.otpw}/lib/security/pam_otpw.so"}
+ ${optionalString cfg.oathAuth
+ "auth sufficient ${pkgs.oathToolkit}/lib/security/pam_oath.so window=5 usersfile=/etc/users.oath"}
${optionalString config.users.ldap.enable
"auth sufficient ${pam_ldap}/lib/security/pam_ldap.so use_first_pass"}
${optionalString config.krb5.enable ''
@@ -174,9 +226,11 @@ let
auth [default=die success=done] ${pam_ccreds}/lib/security/pam_ccreds.so action=validate use_first_pass
auth sufficient ${pam_ccreds}/lib/security/pam_ccreds.so action=store use_first_pass
''}
- auth required pam_deny.so
+ ${optionalString (! config.security.pam.enableEcryptfs) "auth required pam_deny.so"}
# Password management.
+ ${optionalString config.security.pam.enableEcryptfs
+ "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
password requisite pam_unix.so nullok sha512
${optionalString config.users.ldap.enable
"password sufficient ${pam_ldap}/lib/security/pam_ldap.so"}
@@ -192,14 +246,20 @@ let
"session ${
if config.boot.isContainer then "optional" else "required"
} pam_loginuid.so"}
+ ${optionalString cfg.makeHomeDir
+ "session required ${pkgs.pam}/lib/security/pam_mkhomedir.so silent skel=/etc/skel umask=0022"}
${optionalString cfg.updateWtmp
"session required ${pkgs.pam}/lib/security/pam_lastlog.so silent"}
+ ${optionalString config.security.pam.enableEcryptfs
+ "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
${optionalString config.users.ldap.enable
"session optional ${pam_ldap}/lib/security/pam_ldap.so"}
${optionalString config.krb5.enable
"session optional ${pam_krb5}/lib/security/pam_krb5.so"}
${optionalString cfg.otpwAuth
"session optional ${pkgs.otpw}/lib/security/pam_otpw.so"}
+ ${optionalString cfg.oathAuth
+ "session optional ${pkgs.oathToolkit}/lib/security/pam_oath.so window=5 usersfile=/etc/users.oath"}
${optionalString cfg.startSession
"session optional ${pkgs.systemd}/lib/security/pam_systemd.so"}
${optionalString cfg.forwardXAuth
@@ -297,6 +357,20 @@ in
'';
};
+ security.pam.enableOATH = mkOption {
+ default = false;
+ description = ''
+ Enable the OATH (one-time password) PAM module.
+ '';
+ };
+
+ security.pam.enableEcryptfs = mkOption {
+ default = false;
+ description = ''
+ Enable eCryptfs PAM module (mounting ecryptfs home directory on login).
+ '';
+ };
+
users.motd = mkOption {
default = null;
example = "Today is Sweetmorn, the 4th day of The Aftermath in the YOLD 3178.";
@@ -316,7 +390,12 @@ in
[ pkgs.pam ]
++ optional config.users.ldap.enable pam_ldap
++ optionals config.krb5.enable [pam_krb5 pam_ccreds]
- ++ optionals config.security.pam.enableOTPW [ pkgs.otpw ];
+ ++ optionals config.security.pam.enableOTPW [ pkgs.otpw ]
+ ++ optionals config.security.pam.enableOATH [ pkgs.oathToolkit ]
+ ++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ];
+
+ security.setuidPrograms =
+ optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ];
environment.etc =
mapAttrsToList (n: v: makePAMService v) config.security.pam.services;
diff --git a/nixos/modules/security/rngd.nix b/nixos/modules/security/rngd.nix
index 4d8fabc7696..b14ea7a5f27 100644
--- a/nixos/modules/security/rngd.nix
+++ b/nixos/modules/security/rngd.nix
@@ -20,7 +20,7 @@ with lib;
KERNEL=="random", TAG+="systemd"
SUBSYSTEM=="cpu", ENV{MODALIAS}=="x86cpu:*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
KERNEL=="hw_random", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
- KERNEL=="tmp0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"
+ ${if config.services.tcsd.enable then "" else ''KERNEL=="tpm0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service"''}
'';
systemd.services.rngd = {
@@ -32,8 +32,6 @@ with lib;
serviceConfig.ExecStart = "${pkgs.rng_tools}/sbin/rngd -f -v" +
(if config.services.tcsd.enable then " --no-tpm=1" else "");
-
- restartTriggers = [ pkgs.rng_tools ];
};
};
}
diff --git a/nixos/modules/security/setuid-wrappers.nix b/nixos/modules/security/setuid-wrappers.nix
index 373afffd3fb..2a289dc402c 100644
--- a/nixos/modules/security/setuid-wrappers.nix
+++ b/nixos/modules/security/setuid-wrappers.nix
@@ -76,8 +76,7 @@ in
config = {
- security.setuidPrograms =
- [ "fusermount" "wodim" "cdrdao" "growisofs" ];
+ security.setuidPrograms = [ "fusermount" ];
system.activationScripts.setuid =
let
diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix
index cbd1628caae..bced2a6ed75 100644
--- a/nixos/modules/security/sudo.nix
+++ b/nixos/modules/security/sudo.nix
@@ -46,6 +46,14 @@ in
sudoers file.
'';
};
+
+ security.sudo.extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration text appended to sudoers .
+ '';
+ };
};
@@ -55,7 +63,8 @@ in
security.sudo.configFile =
''
- # Don't edit this file. Set the NixOS option ‘security.sudo.configFile’ instead.
+ # Don't edit this file. Set the NixOS options ‘security.sudo.configFile’
+ # or ‘security.sudo.extraConfig’ instead.
# Environment variables to keep for root and %wheel.
Defaults:root,%wheel env_keep+=TERMINFO_DIRS
@@ -68,7 +77,8 @@ in
root ALL=(ALL) SETENV: ALL
# Users in the "wheel" group can do anything.
- %wheel ALL=(ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
+ %wheel ALL=(ALL:ALL) ${if cfg.wheelNeedsPassword then "" else "NOPASSWD: ALL, "}SETENV: ALL
+ ${cfg.extraConfig}
'';
security.setuidPrograms = [ "sudo" "sudoedit" ];
@@ -80,11 +90,10 @@ in
environment.etc = singleton
{ source =
pkgs.runCommand "sudoers"
- {src = pkgs.writeText "sudoers-in" cfg.configFile; }
+ { src = pkgs.writeText "sudoers-in" cfg.configFile; }
# Make sure that the sudoers file is syntactically valid.
# (currently disabled - NIXOS-66)
- "${pkgs.sudo}/sbin/visudo -f $src -c &&
- cp $src $out";
+ "${pkgs.sudo}/sbin/visudo -f $src -c && cp $src $out";
target = "sudoers";
mode = "0440";
};
diff --git a/nixos/modules/services/amqp/rabbitmq.nix b/nixos/modules/services/amqp/rabbitmq.nix
index a930098bfee..780d5daded9 100644
--- a/nixos/modules/services/amqp/rabbitmq.nix
+++ b/nixos/modules/services/amqp/rabbitmq.nix
@@ -31,6 +31,15 @@ in {
guest by default, so you should delete
this user if you intend to allow external access.
'';
+ type = types.str;
+ };
+
+ port = mkOption {
+ default = 5672;
+ description = ''
+ Port on which RabbitMQ will listen for AMQP connections.
+ '';
+ type = types.int;
};
dataDir = mkOption {
@@ -77,6 +86,7 @@ in {
users.extraUsers.rabbitmq = {
description = "RabbitMQ server user";
home = "${cfg.dataDir}";
+ createHome = true;
group = "rabbitmq";
uid = config.ids.uids.rabbitmq;
};
@@ -87,12 +97,16 @@ in {
description = "RabbitMQ Server";
wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
+ after = [ "network.target" ];
+
+ path = [ pkgs.rabbitmq_server pkgs.procps ];
environment = {
RABBITMQ_MNESIA_BASE = "${cfg.dataDir}/mnesia";
RABBITMQ_NODE_IP_ADDRESS = cfg.listenAddress;
+ RABBITMQ_NODE_PORT = toString cfg.port;
RABBITMQ_SERVER_START_ARGS = "-rabbit error_logger tty -rabbit sasl_error_logger false";
+ RABBITMQ_PID_FILE = "${cfg.dataDir}/pid";
SYS_PREFIX = "";
RABBITMQ_ENABLED_PLUGINS_FILE = pkgs.writeText "enabled_plugins" ''
[ ${concatStringsSep "," cfg.plugins} ].
@@ -101,23 +115,21 @@ in {
serviceConfig = {
ExecStart = "${pkgs.rabbitmq_server}/sbin/rabbitmq-server";
+ ExecStop = "${pkgs.rabbitmq_server}/sbin/rabbitmqctl stop";
User = "rabbitmq";
Group = "rabbitmq";
- PermissionsStartOnly = true;
+ WorkingDirectory = cfg.dataDir;
};
+ postStart = ''
+ rabbitmqctl wait ${cfg.dataDir}/pid
+ '';
+
preStart = ''
- mkdir -p ${cfg.dataDir} && chmod 0700 ${cfg.dataDir}
- if [ "$(id -u)" = 0 ]; then chown rabbitmq:rabbitmq ${cfg.dataDir}; fi
-
${optionalString (cfg.cookie != "") ''
echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
chmod 400 ${cfg.dataDir}/.erlang.cookie
- chown rabbitmq:rabbitmq ${cfg.dataDir}/.erlang.cookie
''}
-
- mkdir -p /var/log/rabbitmq && chmod 0700 /var/log/rabbitmq
- chown rabbitmq:rabbitmq /var/log/rabbitmq
'';
};
diff --git a/nixos/modules/services/audio/icecast.nix b/nixos/modules/services/audio/icecast.nix
new file mode 100644
index 00000000000..6a8a0f9975b
--- /dev/null
+++ b/nixos/modules/services/audio/icecast.nix
@@ -0,0 +1,130 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.icecast;
+ configFile = pkgs.writeText "icecast.xml" ''
+
+ ${cfg.hostname}
+
+
+ ${cfg.admin.user}
+ ${cfg.admin.password}
+
+
+
+ ${cfg.logDir}
+ ${pkgs.icecast}/share/icecast/admin
+ ${pkgs.icecast}/share/icecast/web
+
+
+
+
+ ${toString cfg.listen.port}
+ ${cfg.listen.address}
+
+
+
+ 0
+
+ ${cfg.user}
+ ${cfg.group}
+
+
+
+ ${cfg.extraConf}
+
+ '';
+in {
+
+ ###### interface
+
+ options = {
+
+ services.icecast = {
+
+ enable = mkEnableOption "Icecast server";
+
+ hostname = mkOption {
+ type = types.str;
+ description = "DNS name or IP address that will be used for the stream directory lookups or possibily the playlist generation if a Host header is not provided.";
+ default = config.networking.domain;
+ };
+
+ admin = {
+ user = mkOption {
+ type = types.str;
+ description = "Username used for all administration functions.";
+ default = "admin";
+ };
+
+ password = mkOption {
+ type = types.str;
+ description = "Password used for all administration functions.";
+ };
+ };
+
+ logDir = mkOption {
+ type = types.path;
+ description = "Base directory used for logging.";
+ default = "/var/log/icecast";
+ };
+
+ listen = {
+ port = mkOption {
+ type = types.int;
+ description = "TCP port that will be used to accept client connections.";
+ default = 8000;
+ };
+
+ address = mkOption {
+ type = types.str;
+ description = "Address Icecast will listen on.";
+ default = "::";
+ };
+ };
+
+ user = mkOption {
+ type = types.str;
+ description = "User privileges for the server.";
+ default = "nobody";
+ };
+
+ group = mkOption {
+ type = types.str;
+ description = "Group privileges for the server.";
+ default = "nogroup";
+ };
+
+ extraConf = mkOption {
+ type = types.lines;
+ description = "icecast.xml content.";
+ default = "";
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ systemd.services.icecast = {
+ after = [ "network.target" ];
+ description = "Icecast Network Audio Streaming Server";
+ wantedBy = [ "multi-user.target" ];
+
+ preStart = "mkdir -p ${cfg.logDir} && chown ${cfg.user}:${cfg.group} ${cfg.logDir}";
+ serviceConfig = {
+ Type = "simple";
+ ExecStart = "${pkgs.icecast}/bin/icecast -c ${configFile}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/audio/liquidsoap.nix b/nixos/modules/services/audio/liquidsoap.nix
new file mode 100644
index 00000000000..bf67d2399eb
--- /dev/null
+++ b/nixos/modules/services/audio/liquidsoap.nix
@@ -0,0 +1,74 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ streams = builtins.attrNames config.services.liquidsoap.streams;
+
+ streamService =
+ name:
+ let stream = builtins.getAttr name config.services.liquidsoap.streams; in
+ { inherit name;
+ value = {
+ after = [ "network-online.target" "sound.target" ];
+ description = "${name} liquidsoap stream";
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.wget ];
+ preStart =
+ ''
+ mkdir -p /var/log/liquidsoap
+ chown liquidsoap -R /var/log/liquidsoap
+ '';
+ serviceConfig = {
+ PermissionsStartOnly="true";
+ ExecStart = "${pkgs.liquidsoap}/bin/liquidsoap ${stream}";
+ User = "liquidsoap";
+ };
+ };
+ };
+in
+{
+
+ ##### interface
+
+ options = {
+
+ services.liquidsoap.streams = mkOption {
+
+ description =
+ ''
+ Set of Liquidsoap streams to start,
+ one systemd service per stream.
+ '';
+
+ default = {};
+
+ example = {
+ myStream1 = literalExample "\"/etc/liquidsoap/myStream1.liq\"";
+ myStream2 = literalExample "./myStream2.liq";
+ myStream3 = literalExample "\"out(playlist(\"/srv/music/\"))\"";
+ };
+
+ type = types.attrsOf (types.either types.path types.str);
+ };
+
+ };
+ ##### implementation
+
+ config = mkIf (builtins.length streams != 0) {
+
+ users.extraUsers.liquidsoap = {
+ uid = config.ids.uids.liquidsoap;
+ group = "liquidsoap";
+ extraGroups = [ "audio" ];
+ description = "Liquidsoap streaming user";
+ home = "/var/lib/liquidsoap";
+ createHome = true;
+ };
+
+ users.extraGroups.liquidsoap.gid = config.ids.gids.liquidsoap;
+
+ systemd.services = builtins.listToAttrs ( map streamService streams );
+ };
+
+}
diff --git a/nixos/modules/services/audio/mpd.nix b/nixos/modules/services/audio/mpd.nix
index 53542e34b14..d9b5bf7b5e6 100644
--- a/nixos/modules/services/audio/mpd.nix
+++ b/nixos/modules/services/audio/mpd.nix
@@ -15,53 +15,87 @@ let
state_file "${cfg.dataDir}/state"
sticker_file "${cfg.dataDir}/sticker.sql"
log_file "syslog"
- user "mpd"
+ user "${cfg.user}"
+ group "${cfg.group}"
+
+ ${optionalString (cfg.network.host != "any") ''bind_to_address "${cfg.network.host}"''}
+ ${optionalString (cfg.network.port != 6600) ''port "${toString cfg.network.port}"''}
+
${cfg.extraConfig}
- '';
+ '';
in {
###### interface
- options = {
+ options = {
- services.mpd = {
+ services.mpd = {
enable = mkOption {
default = false;
description = ''
Whether to enable MPD, the music player daemon.
- '';
- };
+ '';
+ };
musicDirectory = mkOption {
default = "${cfg.dataDir}/music";
description = ''
- Extra configuration added to the end of MPD's
- configuration file, mpd.conf.
- '';
- };
+ The directory where mpd reads music from.
+ '';
+ };
extraConfig = mkOption {
- default = "";
+ default = "";
description = ''
Extra directives added to to the end of MPD's configuration file,
mpd.conf. Basic configuration like file location and uid/gid
is added automatically to the beginning of the file.
- '';
- };
+ '';
+ };
dataDir = mkOption {
default = "/var/lib/mpd";
description = ''
The directory where MPD stores its state, tag cache,
playlists etc.
- '';
- };
+ '';
+ };
- };
+ user = mkOption {
+ default = "mpd";
+ description = "User account under which MPD runs.";
+ };
- };
+ group = mkOption {
+ default = "mpd";
+ description = "Group account under which MPD runs.";
+ };
+
+ network = {
+
+ host = mkOption {
+ default = "any";
+ description = ''
+ This setting sets the address for the daemon to listen on. Careful attention
+ should be paid if this is assigned to anything other then the default, any.
+ This setting can deny access to control of the daemon.
+ '';
+ };
+
+ port = mkOption {
+ default = 6600;
+ description = ''
+ This setting is the TCP port that is desired for the daemon to get assigned
+ to.
+ '';
+ };
+
+ };
+ };
+
+ };
###### implementation
@@ -73,20 +107,27 @@ in {
description = "Music Player Daemon";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.mpd ];
- preStart = "mkdir -p ${cfg.dataDir} && chown -R mpd:mpd ${cfg.dataDir}";
+ preStart = "mkdir -p ${cfg.dataDir} && chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}";
script = "exec mpd --no-daemon ${mpdConf}";
+ serviceConfig = {
+ User = "mpd";
+ PermissionsStartOnly = true;
+ };
};
- users.extraUsers.mpd = {
+ users.extraUsers = optionalAttrs (cfg.user == "mpd") (singleton {
inherit uid;
- group = "mpd";
+ name = "mpd";
+ group = cfg.group;
extraGroups = [ "audio" ];
description = "Music Player Daemon user";
home = "${cfg.dataDir}";
- };
-
- users.extraGroups.mpd.gid = gid;
+ });
+ users.extraGroups = optionalAttrs (cfg.group == "mpd") (singleton {
+ name = "mpd";
+ gid = gid;
+ });
};
}
diff --git a/nixos/modules/services/backup/almir.nix b/nixos/modules/services/backup/almir.nix
index 5ce215c5c4b..ec39a997028 100644
--- a/nixos/modules/services/backup/almir.nix
+++ b/nixos/modules/services/backup/almir.nix
@@ -109,6 +109,7 @@ in {
};
sqlalchemy_engine_url = mkOption {
+ default = "postgresql:///bacula";
example = ''
postgresql://bacula:bacula@localhost:5432/bacula
mysql+mysqlconnector://:@/'
diff --git a/nixos/modules/services/backup/crashplan.nix b/nixos/modules/services/backup/crashplan.nix
new file mode 100644
index 00000000000..74643d1d463
--- /dev/null
+++ b/nixos/modules/services/backup/crashplan.nix
@@ -0,0 +1,63 @@
+{ config, pkgs, lib, ... }:
+
+let
+ cfg = config.services.crashplan;
+ crashplan = pkgs.crashplan;
+ varDir = "/var/lib/crashplan";
+in
+
+with lib;
+
+{
+ options = {
+ services.crashplan = {
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Starts crashplan background service.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ crashplan ];
+
+ systemd.services.crashplan = {
+ description = "CrashPlan Backup Engine";
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ preStart = ''
+ ensureDir() {
+ dir=$1
+ mode=$2
+
+ if ! test -e $dir; then
+ ${pkgs.coreutils}/bin/mkdir -m $mode -p $dir
+ elif [ "$(${pkgs.coreutils}/bin/stat -c %a $dir)" != "$mode" ]; then
+ ${pkgs.coreutils}/bin/chmod $mode $dir
+ fi
+ }
+
+ ensureDir ${crashplan.vardir} 755
+ ensureDir ${crashplan.vardir}/conf 700
+ ensureDir ${crashplan.manifestdir} 700
+ ensureDir ${crashplan.vardir}/cache 700
+ ensureDir ${crashplan.vardir}/backupArchives 700
+ ensureDir ${crashplan.vardir}/log 777
+ '';
+
+ serviceConfig = {
+ Type = "forking";
+ EnvironmentFile = "${crashplan}/bin/run.conf";
+ ExecStart = "${crashplan}/bin/CrashPlanEngine start";
+ ExecStop = "${crashplan}/bin/CrashPlanEngine stop";
+ PIDFile = "${crashplan.vardir}/CrashPlanEngine.pid";
+ WorkingDirectory = crashplan;
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/backup/rsnapshot.nix b/nixos/modules/services/backup/rsnapshot.nix
index 091b5cfd4d5..fb25bd9dd1e 100644
--- a/nixos/modules/services/backup/rsnapshot.nix
+++ b/nixos/modules/services/backup/rsnapshot.nix
@@ -39,11 +39,20 @@ in
as retain options.
'';
};
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.rsnapshot;
+ example = literalExample "pkgs.rsnapshotGit";
+ description = ''
+ RSnapshot package to use.
+ '';
+ };
};
};
config = mkIf cfg.enable (let
- myRsnapshot = pkgs.rsnapshot.override { configFile = rsnapshotCfg; };
+ myRsnapshot = cfg.package.override { configFile = rsnapshotCfg; };
rsnapshotCfg = with pkgs; writeText "gen-rsnapshot.conf" (''
config_version 1.2
cmd_cp ${coreutils}/bin/cp
diff --git a/nixos/modules/services/backup/tarsnap.nix b/nixos/modules/services/backup/tarsnap.nix
index 1b0bcadca15..155161945cd 100644
--- a/nixos/modules/services/backup/tarsnap.nix
+++ b/nixos/modules/services/backup/tarsnap.nix
@@ -12,6 +12,7 @@ let
keyfile ${config.services.tarsnap.keyfile}
${optionalString cfg.nodump "nodump"}
${optionalString cfg.printStats "print-stats"}
+ ${optionalString cfg.printStats "humanize-numbers"}
${optionalNullStr cfg.checkpointBytes "checkpoint-bytes "+cfg.checkpointBytes}
${optionalString cfg.aggressiveNetworking "aggressive-networking"}
${concatStringsSep "\n" (map (v: "exclude "+v) cfg.excludes)}
@@ -27,46 +28,39 @@ in
type = types.bool;
default = false;
description = ''
- If enabled, NixOS will periodically create backups of the
- specified directories using the tarsnap
- backup service. This installs a systemd
- service called tarsnap-backup which is
- periodically run by cron, or you may run it on-demand.
-
- See the Tarsnap Getting
- Started page.
+ Enable periodic tarsnap backups.
'';
};
keyfile = mkOption {
- type = types.path;
+ type = types.str;
default = "/root/tarsnap.key";
description = ''
- Path to the keyfile which identifies the machine
- associated with your Tarsnap account. This file can
- be created using the
- tarsnap-keygen utility, and
- providing your Tarsnap login credentials.
+ The keyfile which associates this machine with your tarsnap
+ account.
+ Create the keyfile with tarsnap-keygen .
+
+ The keyfile name should be given as a string and not a path, to
+ avoid the key being copied into the Nix store.
'';
};
cachedir = mkOption {
- type = types.path;
+ type = types.nullOr types.path;
default = "/var/cache/tarsnap";
description = ''
- Tarsnap operations use a "cache directory" which
- allows Tarsnap to identify which blocks of data have
- been previously stored; this directory is specified
- via the cachedir option. If the
- cache directory is lost or out of date, tarsnap
- creation/deletion operations will exit with an error
- message instructing you to run tarsnap
- --fsck to regenerate the cache directory.
+ The cache allows tarsnap to identify previously stored data
+ blocks, reducing archival time and bandwidth usage.
+
+ Should the cache become desynchronized or corrupted, tarsnap
+ will refuse to run until you manually rebuild the cache with
+ tarsnap --fsck .
+
+ Set to null to disable caching.
'';
};
- config = mkOption {
+ archives = mkOption {
type = types.attrsOf (types.submodule (
{
options = {
@@ -74,41 +68,44 @@ in
type = types.bool;
default = true;
description = ''
- If set to true , then don't
- archive files which have the
- nodump flag set.
+ Exclude files with the nodump flag.
'';
};
printStats = mkOption {
type = types.bool;
default = true;
- description = "Print statistics when creating archives.";
+ description = ''
+ Print global archive statistics upon completion.
+ The output is available via
+ systemctl status tarsnap@archive-name .
+ '';
};
checkpointBytes = mkOption {
type = types.nullOr types.str;
- default = "1G";
+ default = "1GB";
description = ''
- Create a checkpoint per a particular amount of
- uploaded data. By default, Tarsnap will create
- checkpoints once per GB of data uploaded. At
- minimum, checkpointBytes must be
- 1GB.
+ Create a checkpoint every checkpointBytes
+ of uploaded data (optionally specified using an SI prefix).
- Can also be set to null to
- disable checkpointing.
+ 1GB is the minimum value. A higher value is recommended,
+ as checkpointing is expensive.
+
+ Set to null to disable checkpointing.
'';
};
period = mkOption {
type = types.str;
- default = "15 01 * * *";
+ default = "01:15";
+ example = "hourly";
description = ''
- This option defines (in the format used by cron)
- when tarsnap is run for backups. The default is to
- backup the specified paths at 01:15 at night every
- day.
+ Create archive at this interval.
+
+ The format is described in
+ systemd.time
+ 7 .
'';
};
@@ -116,11 +113,11 @@ in
type = types.bool;
default = false;
description = ''
- Aggressive network behaviour: Use multiple TCP
- connections when writing archives. Use of this
- option is recommended only in cases where TCP
- congestion control is known to be the limiting
- factor in upload performance.
+ Upload data over multiple TCP connections, potentially
+ increasing tarsnap's bandwidth utilisation at the cost
+ of slowing down all other network traffic. Not
+ recommended unless TCP congestion is the dominant
+ limiting factor.
'';
};
@@ -134,8 +131,7 @@ in
type = types.listOf types.str;
default = [];
description = ''
- Exclude files and directories matching the specified
- patterns.
+ Exclude files and directories matching these patterns.
'';
};
@@ -143,12 +139,10 @@ in
type = types.listOf types.str;
default = [];
description = ''
- Include only files and directories matching the
- specified patterns.
+ Include only files and directories matching these
+ patterns (the empty list includes everything).
- Note that exclusions specified via
- excludes take precedence over
- inclusions.
+ Exclusions have precedence over inclusions.
'';
};
@@ -156,10 +150,10 @@ in
type = types.bool;
default = false;
description = ''
- Attempt to reduce tarsnap memory consumption. This
- option will slow down the process of creating
- archives, but may help on systems where the average
- size of files being backed up is less than 1 MB.
+ Reduce memory consumption by not caching small files.
+ Possibly beneficial if the average file size is smaller
+ than 1 MB and the number of files is lower than the
+ total amount of RAM in KB.
'';
};
@@ -167,11 +161,9 @@ in
type = types.bool;
default = false;
description = ''
- Try even harder to reduce tarsnap memory
- consumption. This can significantly slow down
- tarsnap, but reduces its memory usage by an
- additional factor of 2 beyond what the
- lowmem option does.
+ Reduce memory consumption by a factor of 2 beyond what
+ lowmem does, at the cost of significantly
+ slowing down the archiving process.
'';
};
};
@@ -188,25 +180,22 @@ in
gamedata =
{ directories = [ "/var/lib/minecraft "];
- period = "*/30 * * * *";
+ period = "*:30";
};
}
'';
description = ''
- Configuration of a Tarsnap archive. In the example, your
- machine will have two tarsnap archives:
- gamedata (backed up every 30 minutes) and
- nixos (backed up at 1:15 AM every night by
- default). You can control individual archive backups using
- systemctl , using the
- tarsnap@nixos or
- tarsnap@gamedata units. For example,
- systemctl start tarsnap@nixos will
- immediately create a new NixOS archive. By default, archives
- are suffixed with the timestamp of when they were started,
- down to second resolution. This means you can use GNU
- sort to sort output easily.
+ Tarsnap archive configurations. Each attribute names an archive
+ to be created at a given time interval, according to the options
+ associated with it. When uploading to the tarsnap server,
+ archive names are suffixed by a 1 second resolution timestamp.
+
+ For each member of the set is created a timer which triggers the
+ instanced tarsnap@ service unit. You may use
+ systemctl start tarsnap@archive-name to
+ manually trigger creation of archive-name at
+ any time.
'';
};
};
@@ -216,38 +205,45 @@ in
assertions =
(mapAttrsToList (name: cfg:
{ assertion = cfg.directories != [];
- message = "Must specify directories for Tarsnap to back up";
- }) cfg.config) ++
+ message = "Must specify paths for tarsnap to back up";
+ }) cfg.archives) ++
(mapAttrsToList (name: cfg:
- { assertion = cfg.lowmem -> !cfg.verylowmem && (cfg.verylowmem -> !cfg.lowmem);
+ { assertion = !(cfg.lowmem && cfg.verylowmem);
message = "You cannot set both lowmem and verylowmem";
- }) cfg.config);
+ }) cfg.archives);
systemd.services."tarsnap@" = {
- description = "Tarsnap Backup of '%i'";
+ description = "Tarsnap archive '%i'";
requires = [ "network.target" ];
path = [ pkgs.tarsnap pkgs.coreutils ];
scriptArgs = "%i";
script = ''
- mkdir -p -m 0755 $(dirname ${cfg.cachedir})
- mkdir -p -m 0600 ${cfg.cachedir}
+ mkdir -p -m 0755 ${dirOf cfg.cachedir}
+ mkdir -p -m 0700 ${cfg.cachedir}
DIRS=`cat /etc/tarsnap/$1.dirs`
exec tarsnap --configfile /etc/tarsnap/$1.conf -c -f $1-$(date +"%Y%m%d%H%M%S") $DIRS
'';
+
+ serviceConfig = {
+ IOSchedulingClass = "idle";
+ NoNewPrivileges = "true";
+ CapabilityBoundingSet = "CAP_DAC_READ_SEARCH";
+ };
};
- services.cron.systemCronJobs = mapAttrsToList (name: cfg:
- "${cfg.period} root ${config.systemd.package}/bin/systemctl start tarsnap@${name}"
- ) cfg.config;
+ systemd.timers = mapAttrs' (name: cfg: nameValuePair "tarsnap@${name}"
+ { timerConfig.OnCalendar = cfg.period;
+ wantedBy = [ "timers.target" ];
+ }) cfg.archives;
environment.etc =
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.conf"
{ text = configFile cfg;
- }) cfg.config) //
+ }) cfg.archives) //
(mapAttrs' (name: cfg: nameValuePair "tarsnap/${name}.dirs"
{ text = concatStringsSep " " cfg.directories;
- }) cfg.config);
+ }) cfg.archives);
environment.systemPackages = [ pkgs.tarsnap ];
};
diff --git a/nixos/modules/services/cluster/fleet.nix b/nixos/modules/services/cluster/fleet.nix
new file mode 100644
index 00000000000..04d95fbf186
--- /dev/null
+++ b/nixos/modules/services/cluster/fleet.nix
@@ -0,0 +1,150 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.fleet;
+
+in {
+
+ ##### Interface
+ options.services.fleet = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable fleet service.
+ '';
+ };
+
+ listen = mkOption {
+ type = types.listOf types.str;
+ default = [ "/var/run/fleet.sock" ];
+ example = [ "/var/run/fleet.sock" "127.0.0.1:49153" ];
+ description = ''
+ Fleet listening addresses.
+ '';
+ };
+
+ etcdServers = mkOption {
+ type = types.listOf types.str;
+ default = [ "http://127.0.0.1:4001" ];
+ description = ''
+ Fleet list of etcd endpoints to use.
+ '';
+ };
+
+ publicIp = mkOption {
+ type = types.nullOr types.str;
+ default = "";
+ description = ''
+ Fleet IP address that should be published with the local Machine's
+ state and any socket information. If not set, fleetd will attempt
+ to detect the IP it should publish based on the machine's IP
+ routing information.
+ '';
+ };
+
+ etcdCafile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Fleet TLS ca file when SSL certificate authentication is enabled
+ in etcd endpoints.
+ '';
+ };
+
+ etcdKeyfile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Fleet TLS key file when SSL certificate authentication is enabled
+ in etcd endpoints.
+ '';
+ };
+
+ etcdCertfile = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Fleet TLS cert file when SSL certificate authentication is enabled
+ in etcd endpoints.
+ '';
+ };
+
+ metadata = mkOption {
+ type = types.attrsOf types.str;
+ default = {};
+ apply = attrs: concatMapStringsSep "," (n: "${n}=${attrs."${n}"}") (attrNames attrs);
+ example = literalExample ''
+ {
+ region = "us-west";
+ az = "us-west-1";
+ }
+ '';
+ description = ''
+ Key/value pairs that are published with the local to the fleet registry.
+ This data can be used directly by a client of fleet to make scheduling decisions.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.attrsOf types.str;
+ apply = mapAttrs' (n: v: nameValuePair ("ETCD_" + n) v);
+ default = {};
+ example = literalExample ''
+ {
+ VERBOSITY = 1;
+ ETCD_REQUEST_TIMEOUT = "2.0";
+ AGENT_TTL = "40s";
+ }
+ '';
+ description = ''
+ Fleet extra config. See
+
+ for configuration options.
+ '';
+ };
+
+ };
+
+ ##### Implementation
+ config = mkIf cfg.enable {
+ systemd.services.fleet = {
+ description = "Fleet Init System Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "fleet.socket" "etcd.service" "docker.service" ];
+ requires = [ "fleet.socket" ];
+ environment = {
+ FLEET_ETCD_SERVERS = concatStringsSep "," cfg.etcdServers;
+ FLEET_PUBLIC_IP = cfg.publicIp;
+ FLEET_ETCD_CAFILE = cfg.etcdCafile;
+ FLEET_ETCD_KEYFILE = cfg.etcdKeyfile;
+ FEELT_ETCD_CERTFILE = cfg.etcdCertfile;
+ FLEET_METADATA = cfg.metadata;
+ } // cfg.extraConfig;
+ serviceConfig = {
+ ExecStart = "${pkgs.fleet}/bin/fleetd";
+ Group = "fleet";
+ };
+ };
+
+ systemd.sockets.fleet = {
+ description = "Fleet Socket for the API";
+ wantedBy = [ "sockets.target" ];
+ listenStreams = cfg.listen;
+ socketConfig = {
+ ListenStream = "/var/run/fleet.sock";
+ SocketMode = "0660";
+ SocketUser = "root";
+ SocketGroup = "fleet";
+ };
+ };
+
+ services.etcd.enable = mkDefault true;
+ virtualisation.docker.enable = mkDefault true;
+
+ environment.systemPackages = [ pkgs.fleet ];
+ users.extraGroups.fleet.gid = config.ids.gids.fleet;
+ };
+}
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
new file mode 100644
index 00000000000..d9ae0454ba5
--- /dev/null
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -0,0 +1,508 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.kubernetes;
+
+in {
+
+ ###### interface
+
+ options.services.kubernetes = {
+ package = mkOption {
+ description = "Kubernetes package to use.";
+ type = types.package;
+ };
+
+ verbose = mkOption {
+ description = "Kubernetes enable verbose mode for debugging";
+ default = false;
+ type = types.bool;
+ };
+
+ etcdServers = mkOption {
+ description = "Kubernetes list of etcd servers to watch.";
+ default = [ "127.0.0.1:4001" ];
+ type = types.listOf types.str;
+ };
+
+ roles = mkOption {
+ description = ''
+ Kubernetes role that this machine should take.
+
+ Master role will enable etcd, apiserver, scheduler and controller manager
+ services. Node role will enable etcd, docker, kubelet and proxy services.
+ '';
+ default = [];
+ type = types.listOf (types.enum ["master" "node"]);
+ };
+
+ dataDir = mkOption {
+ description = "Kubernetes root directory for managing kubelet files.";
+ default = "/var/lib/kubernetes";
+ type = types.path;
+ };
+
+ dockerCfg = mkOption {
+ description = "Kubernetes contents of dockercfg file.";
+ default = "";
+ type = types.lines;
+ };
+
+ apiserver = {
+ enable = mkOption {
+ description = "Whether to enable kubernetes apiserver.";
+ default = false;
+ type = types.bool;
+ };
+
+ address = mkOption {
+ description = "Kubernetes apiserver listening address.";
+ default = "127.0.0.1";
+ type = types.str;
+ };
+
+ publicAddress = mkOption {
+ description = ''
+ Kubernetes apiserver public listening address used for read only and
+ secure port.
+ '';
+ default = cfg.apiserver.address;
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Kubernets apiserver listening port.";
+ default = 8080;
+ type = types.int;
+ };
+
+ readOnlyPort = mkOption {
+ description = "Kubernets apiserver read-only port.";
+ default = 7080;
+ type = types.int;
+ };
+
+ securePort = mkOption {
+ description = "Kubernetes apiserver secure port.";
+ default = 6443;
+ type = types.int;
+ };
+
+ tlsCertFile = mkOption {
+ description = "Kubernetes apiserver certificate file.";
+ default = "";
+ type = types.str;
+ };
+
+ tlsPrivateKeyFile = mkOption {
+ description = "Kubernetes apiserver private key file.";
+ default = "";
+ type = types.str;
+ };
+
+ tokenAuth = mkOption {
+ description = ''
+ Kubernetes apiserver token authentication file. See
+
+ '';
+ default = {};
+ example = literalExample ''
+ {
+ alice = "abc123";
+ bob = "xyz987";
+ }
+ '';
+ type = types.attrsOf types.str;
+ };
+
+ authorizationMode = mkOption {
+ description = ''
+ Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC). See
+
+ '';
+ default = "AlwaysAllow";
+ type = types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC"];
+ };
+
+ authorizationPolicy = mkOption {
+ description = ''
+ Kubernetes apiserver authorization policy file. See
+
+ '';
+ default = [];
+ example = literalExample ''
+ [
+ {user = "admin";}
+ {user = "scheduler"; readonly = true; kind= "pods";}
+ {user = "scheduler"; kind = "bindings";}
+ {user = "kubelet"; readonly = true; kind = "bindings";}
+ {user = "kubelet"; kind = "events";}
+ {user= "alice"; ns = "projectCaribou";}
+ {user = "bob"; readonly = true; ns = "projectCaribou";}
+ ]
+ '';
+ type = types.listOf types.attrs;
+ };
+
+ allowPrivileged = mkOption {
+ description = "Whether to allow privileged containers on kubernetes.";
+ default = false;
+ type = types.bool;
+ };
+
+ portalNet = mkOption {
+ description = "Kubernetes CIDR notation IP range from which to assign portal IPs";
+ default = "10.10.10.10/16";
+ type = types.str;
+ };
+
+ extraOpts = mkOption {
+ description = "Kubernetes apiserver extra command line options.";
+ default = "";
+ type = types.str;
+ };
+ };
+
+ scheduler = {
+ enable = mkOption {
+ description = "Whether to enable kubernetes scheduler.";
+ default = false;
+ type = types.bool;
+ };
+
+ address = mkOption {
+ description = "Kubernetes scheduler listening address.";
+ default = "127.0.0.1";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Kubernets scheduler listening port.";
+ default = 10251;
+ type = types.int;
+ };
+
+ master = mkOption {
+ description = "Kubernetes apiserver address";
+ default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
+ type = types.str;
+ };
+
+ extraOpts = mkOption {
+ description = "Kubernetes scheduler extra command line options.";
+ default = "";
+ type = types.str;
+ };
+ };
+
+ controllerManager = {
+ enable = mkOption {
+ description = "Whether to enable kubernetes controller manager.";
+ default = false;
+ type = types.bool;
+ };
+
+ address = mkOption {
+ description = "Kubernetes controller manager listening address.";
+ default = "127.0.0.1";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Kubernets controller manager listening port.";
+ default = 10252;
+ type = types.int;
+ };
+
+ master = mkOption {
+ description = "Kubernetes apiserver address";
+ default = "${cfg.apiserver.address}:${toString cfg.apiserver.port}";
+ type = types.str;
+ };
+
+ machines = mkOption {
+ description = "Kubernetes controller list of machines to schedule to schedule onto";
+ default = [];
+ type = types.listOf types.str;
+ };
+
+ extraOpts = mkOption {
+ description = "Kubernetes controller extra command line options.";
+ default = "";
+ type = types.str;
+ };
+ };
+
+ kubelet = {
+ enable = mkOption {
+ description = "Whether to enable kubernetes kubelet.";
+ default = false;
+ type = types.bool;
+ };
+
+ address = mkOption {
+ description = "Kubernetes kubelet info server listening address.";
+ default = "0.0.0.0";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Kubernets kubelet info server listening port.";
+ default = 10250;
+ type = types.int;
+ };
+
+ hostname = mkOption {
+ description = "Kubernetes kubelet hostname override";
+ default = config.networking.hostName;
+ type = types.str;
+ };
+
+ allowPrivileged = mkOption {
+ description = "Whether to allow kubernetes containers to request privileged mode.";
+ default = false;
+ type = types.bool;
+ };
+
+ apiServers = mkOption {
+ description = "Kubernetes kubelet list of Kubernetes API servers for publishing events, and reading pods and services.";
+ default = ["${cfg.apiserver.address}:${toString cfg.apiserver.port}"];
+ type = types.listOf types.str;
+ };
+
+ cadvisorPort = mkOption {
+ description = "Kubernetes kubelet local cadvisor port.";
+ default = config.services.cadvisor.port;
+ type = types.int;
+ };
+
+ clusterDns = mkOption {
+ description = "Use alternative dns.";
+ default = "";
+ type = types.str;
+ };
+
+ clusterDomain = mkOption {
+ description = "Use alternative domain.";
+ default = "";
+ type = types.str;
+ };
+
+ extraOpts = mkOption {
+ description = "Kubernetes kubelet extra command line options.";
+ default = "";
+ type = types.str;
+ };
+ };
+
+ proxy = {
+ enable = mkOption {
+ description = "Whether to enable kubernetes proxy.";
+ default = false;
+ type = types.bool;
+ };
+
+ address = mkOption {
+ description = "Kubernetes proxy listening address.";
+ default = "0.0.0.0";
+ type = types.str;
+ };
+
+ extraOpts = mkOption {
+ description = "Kubernetes proxy extra command line options.";
+ default = "";
+ type = types.str;
+ };
+ };
+ };
+
+ ###### implementation
+
+ config = mkMerge [
+ (mkIf cfg.apiserver.enable {
+ systemd.services.kubernetes-apiserver = {
+ description = "Kubernetes Api Server";
+ wantedBy = [ "multi-user.target" ];
+ requires = ["kubernetes-setup.service"];
+ after = [ "network-interfaces.target" "etcd.service" ];
+ serviceConfig = {
+ ExecStart = let
+ authorizationPolicyFile =
+ pkgs.writeText "kubernetes-policy"
+ (builtins.toJSON cfg.apiserver.authorizationPolicy);
+ tokenAuthFile =
+ pkgs.writeText "kubernetes-auth"
+ (concatImapStringsSep "\n" (i: v: v + "," + (toString i))
+ (mapAttrsToList (name: token: token + "," + name) cfg.apiserver.tokenAuth));
+ in ''${cfg.package}/bin/kube-apiserver \
+ --etcd_servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
+ --address=${cfg.apiserver.address} \
+ --port=${toString cfg.apiserver.port} \
+ --read_only_port=${toString cfg.apiserver.readOnlyPort} \
+ --public_address_override=${cfg.apiserver.publicAddress} \
+ --allow_privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
+ ${optionalString (cfg.apiserver.tlsCertFile!="")
+ "--tls_cert_file=${cfg.apiserver.tlsCertFile}"} \
+ ${optionalString (cfg.apiserver.tlsPrivateKeyFile!="")
+ "--tls_private_key_file=${cfg.apiserver.tlsPrivateKeyFile}"} \
+ ${optionalString (cfg.apiserver.tokenAuth!=[])
+ "--token_auth_file=${tokenAuthFile}"} \
+ --authorization_mode=${cfg.apiserver.authorizationMode} \
+ ${optionalString (cfg.apiserver.authorizationMode == "ABAC")
+ "--authorization_policy_file=${authorizationPolicyFile}"} \
+ --secure_port=${toString cfg.apiserver.securePort} \
+ --portal_net=${cfg.apiserver.portalNet} \
+ --logtostderr=true \
+ ${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
+ ${cfg.apiserver.extraOpts}
+ '';
+ User = "kubernetes";
+ };
+ postStart = ''
+ until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.apiserver.address}:${toString cfg.apiserver.port}/'; do
+ sleep 1;
+ done
+ '';
+ };
+ })
+
+ (mkIf cfg.scheduler.enable {
+ systemd.services.kubernetes-scheduler = {
+ description = "Kubernetes Scheduler Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "kubernetes-apiserver.service" ];
+ serviceConfig = {
+ ExecStart = ''${cfg.package}/bin/kube-scheduler \
+ --address=${cfg.scheduler.address} \
+ --port=${toString cfg.scheduler.port} \
+ --master=${cfg.scheduler.master} \
+ --logtostderr=true \
+ ${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
+ ${cfg.scheduler.extraOpts}
+ '';
+ User = "kubernetes";
+ };
+ };
+ })
+
+ (mkIf cfg.controllerManager.enable {
+ systemd.services.kubernetes-controller-manager = {
+ description = "Kubernetes Controller Manager Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "kubernetes-apiserver.service" ];
+ serviceConfig = {
+ ExecStart = ''${cfg.package}/bin/kube-controller-manager \
+ --address=${cfg.controllerManager.address} \
+ --port=${toString cfg.controllerManager.port} \
+ --master=${cfg.controllerManager.master} \
+ --machines=${concatStringsSep "," cfg.controllerManager.machines} \
+ --logtostderr=true \
+ ${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
+ ${cfg.controllerManager.extraOpts}
+ '';
+ User = "kubernetes";
+ };
+ };
+ })
+
+ (mkIf cfg.kubelet.enable {
+ systemd.services.kubernetes-kubelet = {
+ description = "Kubernetes Kubelet Service";
+ wantedBy = [ "multi-user.target" ];
+ requires = ["kubernetes-setup.service"];
+ after = [ "network-interfaces.target" "etcd.service" "docker.service" ];
+ script = ''
+ export PATH="/bin:/sbin:/usr/bin:/usr/sbin:$PATH"
+ exec ${cfg.package}/bin/kubelet \
+ --etcd_servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
+ --api_servers=${concatMapStringsSep "," (f: "http://${f}") cfg.kubelet.apiServers} \
+ --address=${cfg.kubelet.address} \
+ --port=${toString cfg.kubelet.port} \
+ --hostname_override=${cfg.kubelet.hostname} \
+ --allow_privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
+ --root_dir=${cfg.dataDir} \
+ --cadvisor_port=${toString cfg.kubelet.cadvisorPort} \
+ ${optionalString (cfg.kubelet.clusterDns != "")
+ ''--cluster_dns=${cfg.kubelet.clusterDns}''} \
+ ${optionalString (cfg.kubelet.clusterDomain != "")
+ ''--cluster_domain=${cfg.kubelet.clusterDomain}''} \
+ --logtostderr=true \
+ ${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
+ ${cfg.kubelet.extraOpts}
+ '';
+ serviceConfig.WorkingDirectory = cfg.dataDir;
+ };
+ })
+
+ (mkIf cfg.proxy.enable {
+ systemd.services.kubernetes-proxy = {
+ description = "Kubernetes Proxy Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "etcd.service" ];
+ serviceConfig = {
+ ExecStart = ''${cfg.package}/bin/kube-proxy \
+ --etcd_servers=${concatMapStringsSep "," (s: "http://${s}") cfg.etcdServers} \
+ --bind_address=${cfg.proxy.address} \
+ --logtostderr=true \
+ ${optionalString cfg.verbose "--v=6 --log_flush_frequency=1s"} \
+ ${cfg.proxy.extraOpts}
+ '';
+ };
+ };
+ })
+
+ (mkIf (any (el: el == "master") cfg.roles) {
+ services.kubernetes.apiserver.enable = mkDefault true;
+ services.kubernetes.scheduler.enable = mkDefault true;
+ services.kubernetes.controllerManager.enable = mkDefault true;
+ })
+
+ (mkIf (any (el: el == "node") cfg.roles) {
+ virtualisation.docker.enable = mkDefault true;
+ services.cadvisor.enable = mkDefault true;
+ services.cadvisor.port = mkDefault 4194;
+ services.kubernetes.kubelet.enable = mkDefault true;
+ services.kubernetes.proxy.enable = mkDefault true;
+ })
+
+ (mkIf (any (el: el == "node" || el == "master") cfg.roles) {
+ services.etcd.enable = mkDefault true;
+ })
+
+ (mkIf (
+ cfg.apiserver.enable ||
+ cfg.scheduler.enable ||
+ cfg.controllerManager.enable ||
+ cfg.kubelet.enable ||
+ cfg.proxy.enable
+ ) {
+ systemd.services.kubernetes-setup = {
+ description = "Kubernetes setup.";
+ serviceConfig.Type = "oneshot";
+ script = ''
+ mkdir -p /var/run/kubernetes
+ chown kubernetes /var/run/kubernetes
+ ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} /var/run/kubernetes/.dockercfg
+ '';
+ };
+
+ services.kubernetes.package = mkDefault pkgs.kubernetes;
+
+ environment.systemPackages = [ cfg.package ];
+
+ users.extraUsers = singleton {
+ name = "kubernetes";
+ uid = config.ids.uids.kubernetes;
+ description = "Kubernetes user";
+ extraGroups = [ "docker" ];
+ group = "kubernetes";
+ home = cfg.dataDir;
+ createHome = true;
+ };
+ users.extraGroups.kubernetes.gid = config.ids.gids.kubernetes;
+ })
+
+ ];
+}
diff --git a/nixos/modules/services/cluster/panamax.nix b/nixos/modules/services/cluster/panamax.nix
new file mode 100644
index 00000000000..b47ff744fc2
--- /dev/null
+++ b/nixos/modules/services/cluster/panamax.nix
@@ -0,0 +1,156 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.panamax;
+
+ panamax_api = pkgs.panamax_api.override { dataDir = cfg.dataDir + "/api"; };
+ panamax_ui = pkgs.panamax_ui.override { dataDir = cfg.dataDir + "/ui"; };
+
+in {
+
+ ##### Interface
+ options.services.panamax = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Panamax service.
+ '';
+ };
+
+ UIPort = mkOption {
+ type = types.int;
+ default = 8888;
+ description = ''
+ Panamax UI listening port.
+ '';
+ };
+
+ APIPort = mkOption {
+ type = types.int;
+ default = 3000;
+ description = ''
+ Panamax UI listening port.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/panamax";
+ description = ''
+ Data dir for Panamax.
+ '';
+ };
+
+ fleetctlEndpoint = mkOption {
+ type = types.str;
+ default = "http://127.0.0.1:4001";
+ description = ''
+ Panamax fleetctl endpoint.
+ '';
+ };
+
+ journalEndpoint = mkOption {
+ type = types.str;
+ default = "http://127.0.0.1:19531";
+ description = ''
+ Panamax journal endpoint.
+ '';
+ };
+
+ secretKey = mkOption {
+ type = types.str;
+ default = "SomethingVeryLong.";
+ description = ''
+ Panamax secret key (do change this).
+ '';
+ };
+
+ };
+
+ ##### Implementation
+ config = mkIf cfg.enable {
+ systemd.services.panamax-api = {
+ description = "Panamax API";
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "fleet.service" "etcd.service" "docker.service" ];
+
+ path = [ panamax_api ];
+ environment = {
+ RAILS_ENV = "production";
+ JOURNAL_ENDPOINT = cfg.journalEndpoint;
+ FLEETCTL_ENDPOINT = cfg.fleetctlEndpoint;
+ PANAMAX_DATABASE_PATH = "${cfg.dataDir}/api/db/mnt/db.sqlite3";
+ };
+
+ preStart = ''
+ rm -rf ${cfg.dataDir}/state/tmp
+ mkdir -p ${cfg.dataDir}/api/{db/mnt,state/log,state/tmp}
+ ln -sf ${panamax_api}/share/panamax-api/_db/{schema.rb,seeds.rb,migrate} ${cfg.dataDir}/api/db/
+
+ if [ ! -f ${cfg.dataDir}/.created ]; then
+ bundle exec rake db:setup
+ bundle exec rake db:seed
+ bundle exec rake panamax:templates:load || true
+ touch ${cfg.dataDir}/.created
+ else
+ bundle exec rake db:migrate
+ fi
+ '';
+
+ serviceConfig = {
+ ExecStart = "${panamax_api}/bin/bundle exec rails server --binding 127.0.0.1 --port ${toString cfg.APIPort}";
+ User = "panamax";
+ Group = "panamax";
+ };
+ };
+
+ systemd.services.panamax-ui = {
+ description = "Panamax UI";
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "panamax_api.service" ];
+
+ path = [ panamax_ui ];
+ environment = {
+ RAILS_ENV = "production";
+ JOURNAL_ENDPOINT = cfg.journalEndpoint;
+ PMX_API_PORT_3000_TCP_ADDR = "localhost";
+ PMX_API_PORT_3000_TCP_PORT = toString cfg.APIPort;
+ SECRET_KEY_BASE = cfg.secretKey;
+ };
+
+ preStart = ''
+ mkdir -p ${cfg.dataDir}/ui/state/{log,tmp}
+ chown -R panamax:panamax ${cfg.dataDir}
+ '';
+
+ serviceConfig = {
+ ExecStart = "${panamax_ui}/bin/bundle exec rails server --binding 127.0.0.1 --port ${toString cfg.UIPort}";
+ User = "panamax";
+ Group = "panamax";
+ PermissionsStartOnly = true;
+ };
+ };
+
+ users.extraUsers.panamax =
+ { uid = config.ids.uids.panamax;
+ description = "Panamax user";
+ createHome = true;
+ home = cfg.dataDir;
+ extraGroups = [ "docker" ];
+ };
+
+ services.journald.enableHttpGateway = mkDefault true;
+ services.fleet.enable = mkDefault true;
+ services.cadvisor.enable = mkDefault true;
+ services.cadvisor.port = mkDefault 3002;
+ virtualisation.docker.enable = mkDefault true;
+
+ environment.systemPackages = [ panamax_api panamax_ui ];
+ users.extraGroups.panamax.gid = config.ids.gids.panamax;
+ };
+}
diff --git a/nixos/modules/services/computing/slurm/slurm.nix b/nixos/modules/services/computing/slurm/slurm.nix
new file mode 100644
index 00000000000..019d7fbb16c
--- /dev/null
+++ b/nixos/modules/services/computing/slurm/slurm.nix
@@ -0,0 +1,130 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.slurm;
+ # configuration file can be generated by http://slurm.schedmd.com/configurator.html
+ configFile = pkgs.writeText "slurm.conf"
+ ''
+ ${optionalString (cfg.controlMachine != null) ''controlMachine=${cfg.controlMachine}''}
+ ${optionalString (cfg.controlAddr != null) ''controlAddr=${cfg.controlAddr}''}
+ ${optionalString (cfg.nodeName != null) ''nodeName=${cfg.nodeName}''}
+ ${optionalString (cfg.partitionName != null) ''partitionName=${cfg.partitionName}''}
+ ${cfg.extraConfig}
+ '';
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.slurm = {
+
+ server = {
+ enable = mkEnableOption "slurm control daemon";
+
+ };
+
+ client = {
+ enable = mkEnableOption "slurm rlient daemon";
+
+ };
+
+ controlMachine = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = null;
+ description = ''
+ The short hostname of the machine where SLURM control functions are
+ executed (i.e. the name returned by the command "hostname -s", use "tux001"
+ rather than "tux001.my.com").
+ '';
+ };
+
+ controlAddr = mkOption {
+ type = types.nullOr types.str;
+ default = cfg.controlMachine;
+ example = null;
+ description = ''
+ Name that ControlMachine should be referred to in establishing a
+ communications path.
+ '';
+ };
+
+ nodeName = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "linux[1-32] CPUs=1 State=UNKNOWN";
+ description = ''
+ Name that SLURM uses to refer to a node (or base partition for BlueGene
+ systems). Typically this would be the string that "/bin/hostname -s"
+ returns. Note that now you have to write node's parameters after the name.
+ '';
+ };
+
+ partitionName = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "debug Nodes=linux[1-32] Default=YES MaxTime=INFINITE State=UP";
+ description = ''
+ Name by which the partition may be referenced. Note that now you have
+ to write patrition's parameters after the name.
+ '';
+ };
+
+ extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Extra configuration options that will be added verbatim at
+ the end of the slurm configuration file.
+ '';
+ };
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf (cfg.client.enable || cfg.server.enable) {
+
+ environment.systemPackages = [ pkgs.slurm-llnl ];
+
+ systemd.services.slurmd = mkIf (cfg.client.enable) {
+ path = with pkgs; [ slurm-llnl coreutils ];
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "systemd-tmpfiles-clean.service" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${pkgs.slurm-llnl}/bin/slurmd -f ${configFile}";
+ PIDFile = "/run/slurmd.pid";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ };
+ };
+
+ systemd.services.slurmctld = mkIf (cfg.server.enable) {
+ path = with pkgs; [ slurm-llnl munge coreutils ];
+
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "auditd.service" "munged.service" "slurmdbd.service" ];
+ requires = [ "munged.service" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${pkgs.slurm-llnl}/bin/slurmctld";
+ PIDFile = "/run/slurmctld.pid";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ };
+ environment = { SLURM_CONF = "${configFile}"; };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/computing/torque/mom.nix b/nixos/modules/services/computing/torque/mom.nix
new file mode 100644
index 00000000000..83772539a7a
--- /dev/null
+++ b/nixos/modules/services/computing/torque/mom.nix
@@ -0,0 +1,63 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.torque.mom;
+ torque = pkgs.torque;
+
+ momConfig = pkgs.writeText "torque-mom-config" ''
+ $pbsserver ${cfg.serverNode}
+ $logevent 225
+ '';
+
+in
+{
+ options = {
+
+ services.torque.mom = {
+ enable = mkEnableOption "torque computing node";
+
+ serverNode = mkOption {
+ type = types.str;
+ description = "Hostname running pbs server.";
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.torque ];
+
+ systemd.services.torque-mom-init = {
+ path = with pkgs; [ torque utillinux procps inetutils ];
+
+ script = ''
+ pbs_mkdirs -v aux
+ pbs_mkdirs -v mom
+ hostname > /var/spool/torque/server_name
+ cp -v ${momConfig} /var/spool/torque/mom_priv/config
+ '';
+
+ serviceConfig.Type = "oneshot";
+ unitConfig.ConditionPathExists = "!/var/spool/torque";
+ };
+
+ systemd.services.torque-mom = {
+ path = [ torque ];
+
+ wantedBy = [ "multi-user.target" ];
+ requires = [ "torque-mom-init.service" ];
+ after = [ "torque-mom-init.service" "network.target" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${torque}/bin/pbs_mom";
+ PIDFile = "/var/spool/torque/mom_priv/mom.lock";
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/computing/torque/server.nix b/nixos/modules/services/computing/torque/server.nix
new file mode 100644
index 00000000000..655d1500497
--- /dev/null
+++ b/nixos/modules/services/computing/torque/server.nix
@@ -0,0 +1,96 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.services.torque.server;
+ torque = pkgs.torque;
+in
+{
+ options = {
+
+ services.torque.server = {
+
+ enable = mkEnableOption "torque server";
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.torque ];
+
+ systemd.services.torque-server-init = {
+ path = with pkgs; [ torque utillinux procps inetutils ];
+
+ script = ''
+ tmpsetup=$(mktemp -t torque-XXXX)
+ cp -p ${torque}/bin/torque.setup $tmpsetup
+ sed -i $tmpsetup -e 's/pbs_server -t create/pbs_server -f -t create/'
+
+ pbs_mkdirs -v aux
+ pbs_mkdirs -v server
+ hostname > /var/spool/torque/server_name
+ cp -prv ${torque}/var/spool/torque/* /var/spool/torque/
+ $tmpsetup root
+
+ sleep 1
+ rm -f $tmpsetup
+ kill $(pgrep pbs_server) 2>/dev/null
+ kill $(pgrep trqauthd) 2>/dev/null
+ '';
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+
+ unitConfig = {
+ ConditionPathExists = "!/var/spool/torque";
+ };
+ };
+
+ systemd.services.trqauthd = {
+ path = [ torque ];
+
+ requires = [ "torque-server-init.service" ];
+ after = [ "torque-server-init.service" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${torque}/bin/trqauthd";
+ };
+ };
+
+ systemd.services.torque-server = {
+ path = [ torque ];
+
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "torque-scheduler.service" "trqauthd.service" ];
+ before = [ "trqauthd.service" ];
+ requires = [ "torque-server-init.service" ];
+ after = [ "torque-server-init.service" "network.target" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${torque}/bin/pbs_server";
+ ExecStop = "${torque}/bin/qterm";
+ PIDFile = "/var/spool/torque/server_priv/server.lock";
+ };
+ };
+
+ systemd.services.torque-scheduler = {
+ path = [ torque ];
+
+ requires = [ "torque-server-init.service" ];
+ after = [ "torque-server-init.service" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${torque}/bin/pbs_sched";
+ PIDFile = "/var/spool/torque/sched_priv/sched.lock";
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/continuous-integration/jenkins/default.nix b/nixos/modules/services/continuous-integration/jenkins/default.nix
index b01b5c3245a..29a81f066ab 100644
--- a/nixos/modules/services/continuous-integration/jenkins/default.nix
+++ b/nixos/modules/services/continuous-integration/jenkins/default.nix
@@ -15,7 +15,7 @@ in {
user = mkOption {
default = "jenkins";
- type = with types; string;
+ type = types.str;
description = ''
User the jenkins server should execute under.
'';
@@ -23,16 +23,25 @@ in {
group = mkOption {
default = "jenkins";
- type = with types; string;
+ type = types.str;
description = ''
If the default user "jenkins" is configured then this is the primary
group of that user.
'';
};
+ extraGroups = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "wheel" "dialout" ];
+ description = ''
+ List of extra groups that the "jenkins" user should be a part of.
+ '';
+ };
+
home = mkOption {
default = "/var/lib/jenkins";
- type = with types; string;
+ type = types.path;
description = ''
The path to use as JENKINS_HOME. If the default user "jenkins" is configured then
this is the home of the "jenkins" user.
@@ -57,12 +66,21 @@ in {
environment = mkOption {
default = { NIX_REMOTE = "daemon"; };
- type = with types; attrsOf string;
+ type = with types; attrsOf str;
description = ''
Additional environment variables to be passed to the jenkins process.
The environment will always include JENKINS_HOME.
'';
};
+
+ extraOptions = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "--debug=9" "--httpListenAddress=localhost" ];
+ description = ''
+ Additional command line arguments to pass to Jenkins.
+ '';
+ };
};
};
@@ -78,6 +96,7 @@ in {
createHome = true;
home = cfg.home;
group = cfg.group;
+ extraGroups = cfg.extraGroups;
useDefaultShell = true;
uid = config.ids.uids.jenkins;
};
@@ -94,7 +113,7 @@ in {
path = cfg.packages;
script = ''
- ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port}
+ ${pkgs.jdk}/bin/java -jar ${pkgs.jenkins} --httpPort=${toString cfg.port} ${concatStringsSep " " cfg.extraOptions}
'';
postStart = ''
diff --git a/nixos/modules/services/continuous-integration/jenkins/slave.nix b/nixos/modules/services/continuous-integration/jenkins/slave.nix
index 5836d92a4fc..a0216caf2b5 100644
--- a/nixos/modules/services/continuous-integration/jenkins/slave.nix
+++ b/nixos/modules/services/continuous-integration/jenkins/slave.nix
@@ -23,7 +23,7 @@ in {
user = mkOption {
default = "jenkins";
- type = with types; string;
+ type = types.str;
description = ''
User the jenkins slave agent should execute under.
'';
@@ -31,7 +31,7 @@ in {
group = mkOption {
default = "jenkins";
- type = with types; string;
+ type = types.str;
description = ''
If the default slave agent user "jenkins" is configured then this is
the primary group of that user.
@@ -40,7 +40,7 @@ in {
home = mkOption {
default = "/var/lib/jenkins";
- type = with types; string;
+ type = types.path;
description = ''
The path to use as JENKINS_HOME. If the default user "jenkins" is configured then
this is the home of the "jenkins" user.
diff --git a/nixos/modules/services/databases/4store-endpoint.nix b/nixos/modules/services/databases/4store-endpoint.nix
index f2d64b6891d..a0379043371 100644
--- a/nixos/modules/services/databases/4store-endpoint.nix
+++ b/nixos/modules/services/databases/4store-endpoint.nix
@@ -56,14 +56,13 @@ with lib;
{ name = endpointUser;
uid = config.ids.uids.fourstorehttp;
description = "4Store SPARQL endpoint user";
-# home = stateDir;
};
services.avahi.enable = true;
jobs.fourStoreEndpoint = {
name = "4store-endpoint";
- startOn = "filesystem";
+ startOn = "ip-up";
exec = ''
${run} '${pkgs.rdf4store}/bin/4s-httpd -D ${cfg.options} ${if cfg.listenAddress!=null then "-H ${cfg.listenAddress}" else "" } -p ${toString cfg.port} ${cfg.database}'
diff --git a/nixos/modules/services/databases/4store.nix b/nixos/modules/services/databases/4store.nix
index 469fef69c95..807317d2745 100644
--- a/nixos/modules/services/databases/4store.nix
+++ b/nixos/modules/services/databases/4store.nix
@@ -54,7 +54,7 @@ with lib;
jobs.fourStore = {
name = "4store";
- startOn = "filesystem";
+ startOn = "ip-up";
preStart = ''
mkdir -p ${stateDir}/
diff --git a/nixos/modules/services/databases/couchdb.nix b/nixos/modules/services/databases/couchdb.nix
index e1fe6be6f6a..2b1d07c355e 100644
--- a/nixos/modules/services/databases/couchdb.nix
+++ b/nixos/modules/services/databases/couchdb.nix
@@ -131,8 +131,8 @@ in {
type = types.string;
default = "/var/lib/couchdb/couchdb.ini";
description = ''
- Custom configuration file. File needs to be readable and writable
- from couchdb user/group.
+ Configuration file for persisting runtime changes. File
+ needs to be readable and writable from couchdb user/group.
'';
};
@@ -157,12 +157,15 @@ in {
mkdir -p ${cfg.databaseDir};
mkdir -p ${cfg.viewIndexDir};
touch ${cfg.configFile}
+ touch -a ${cfg.logFile}
if [ "$(id -u)" = 0 ]; then
- chown ${cfg.user}:${cfg.group} ${cfg.uriFile}
+ chown ${cfg.user}:${cfg.group} `dirname ${cfg.uriFile}`;
+ (-f ${cfg.uriFile} && chown ${cfg.user}:${cfg.group} ${cfg.uriFile}) || true
chown ${cfg.user}:${cfg.group} ${cfg.databaseDir}
chown ${cfg.user}:${cfg.group} ${cfg.viewIndexDir}
chown ${cfg.user}:${cfg.group} ${cfg.configFile}
+ chown ${cfg.user}:${cfg.group} ${cfg.logFile}
fi
'';
diff --git a/nixos/modules/services/databases/hbase.nix b/nixos/modules/services/databases/hbase.nix
new file mode 100644
index 00000000000..ccfabc9de0b
--- /dev/null
+++ b/nixos/modules/services/databases/hbase.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.hbase;
+
+ configFile = pkgs.writeText "hbase-site.xml" ''
+
+
+ hbase.rootdir
+ file://${cfg.dataDir}/hbase
+
+
+ hbase.zookeeper.property.dataDir
+ ${cfg.dataDir}/zookeeper
+
+
+ '';
+
+ configDir = pkgs.runCommand "hbase-config-dir" {} ''
+ mkdir -p $out
+ cp ${cfg.package}/conf/* $out/
+ rm $out/hbase-site.xml
+ ln -s ${configFile} $out/hbase-site.xml
+ '' ;
+
+in {
+
+ ###### interface
+
+ options = {
+
+ services.hbase = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to run HBase.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.hbase;
+ example = literalExample "pkgs.hbase";
+ description = ''
+ HBase package to use.
+ '';
+ };
+
+
+ user = mkOption {
+ type = types.string;
+ default = "hbase";
+ description = ''
+ User account under which HBase runs.
+ '';
+ };
+
+ group = mkOption {
+ type = types.string;
+ default = "hbase";
+ description = ''
+ Group account under which HBase runs.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.path;
+ default = "/var/lib/hbase";
+ description = ''
+ Specifies location of HBase database files. This location should be
+ writable and readable for the user the HBase service runs as
+ (hbase by default).
+ '';
+ };
+
+ logDir = mkOption {
+ type = types.path;
+ default = "/var/log/hbase";
+ description = ''
+ Specifies the location of HBase log files.
+ '';
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf config.services.hbase.enable {
+
+ systemd.services.hbase = {
+ description = "HBase Server";
+ wantedBy = [ "multi-user.target" ];
+
+ environment = {
+ JAVA_HOME = "${pkgs.jre}";
+ HBASE_LOG_DIR = cfg.logDir;
+ };
+
+ preStart =
+ ''
+ mkdir -p ${cfg.dataDir};
+ mkdir -p ${cfg.logDir};
+
+ if [ "$(id -u)" = 0 ]; then
+ chown ${cfg.user}:${cfg.group} ${cfg.dataDir}
+ chown ${cfg.user}:${cfg.group} ${cfg.logDir}
+ fi
+ '';
+
+ serviceConfig = {
+ PermissionsStartOnly = true;
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = "${cfg.package}/bin/hbase --config ${configDir} master start";
+ };
+ };
+
+ users.extraUsers.hbase = {
+ description = "HBase Server user";
+ group = "hbase";
+ uid = config.ids.uids.hbase;
+ };
+
+ users.extraGroups.hbase.gid = config.ids.gids.hbase;
+
+ };
+}
diff --git a/nixos/modules/services/databases/influxdb.nix b/nixos/modules/services/databases/influxdb.nix
index 61fe96d5d64..b57ccebae16 100644
--- a/nixos/modules/services/databases/influxdb.nix
+++ b/nixos/modules/services/databases/influxdb.nix
@@ -224,6 +224,11 @@ in
mkdir -m 0770 -p ${cfg.dataDir}
if [ "$(id -u)" = 0 ]; then chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}; fi
'';
+ postStart = mkBefore ''
+ until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.bindAddress}:${toString cfg.apiPort}/'; do
+ sleep 1;
+ done
+ '';
};
users.extraUsers = optional (cfg.user == "influxdb") {
diff --git a/nixos/modules/services/databases/mongodb.nix b/nixos/modules/services/databases/mongodb.nix
index fe82ca430e1..14ffdad9217 100644
--- a/nixos/modules/services/databases/mongodb.nix
+++ b/nixos/modules/services/databases/mongodb.nix
@@ -15,9 +15,11 @@ let
bind_ip = ${cfg.bind_ip}
${optionalString cfg.quiet "quiet = true"}
dbpath = ${cfg.dbpath}
- logpath = ${cfg.logpath}
- logappend = ${b2s cfg.logappend}
+ syslog = true
+ fork = true
+ pidfilepath = ${cfg.pidFile}
${optionalString (cfg.replSetName != "") "replSet = ${cfg.replSetName}"}
+ ${cfg.extraConfig}
'';
in
@@ -65,14 +67,9 @@ in
description = "Location where MongoDB stores its files";
};
- logpath = mkOption {
- default = "/var/log/mongodb/mongod.log";
- description = "Location where MongoDB stores its logfile";
- };
-
- logappend = mkOption {
- default = true;
- description = "Append logfile instead over overwriting";
+ pidFile = mkOption {
+ default = "/var/run/mongodb.pid";
+ description = "Location of MongoDB pid file";
};
replSetName = mkOption {
@@ -82,6 +79,14 @@ in
Otherwise, leave empty to run as single node.
'';
};
+
+ extraConfig = mkOption {
+ default = "";
+ example = ''
+ nojournal = true
+ '';
+ description = "MongoDB extra configuration";
+ };
};
};
@@ -99,22 +104,6 @@ in
environment.systemPackages = [ mongodb ];
- systemd.services.mongodb_init =
- { description = "MongoDB server initialisation";
-
- wantedBy = [ "mongodb.service" ];
- before = [ "mongodb.service" ];
-
- serviceConfig.Type = "oneshot";
-
- script = ''
- if ! test -e ${cfg.dbpath}; then
- install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
- install -d -m0755 -o ${cfg.user} `dirname ${cfg.logpath}`
- fi
- '';
- };
-
systemd.services.mongodb =
{ description = "MongoDB server";
@@ -124,7 +113,21 @@ in
serviceConfig = {
ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}";
User = cfg.user;
+ PIDFile = cfg.pidFile;
+ Type = "forking";
+ TimeoutStartSec=120; # intial creating of journal can take some time
+ PermissionsStartOnly = true;
};
+
+ preStart = ''
+ rm ${cfg.dbpath}/mongod.lock || true
+ if ! test -e ${cfg.dbpath}; then
+ install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
+ fi
+ if ! test -e ${cfg.pidFile}; then
+ install -D -o ${cfg.user} /dev/null ${cfg.pidFile}
+ fi
+ '';
};
};
diff --git a/nixos/modules/services/databases/mysql.nix b/nixos/modules/services/databases/mysql.nix
index b94a3fbf3de..05b13492052 100644
--- a/nixos/modules/services/databases/mysql.nix
+++ b/nixos/modules/services/databases/mysql.nix
@@ -8,9 +8,7 @@ let
mysql = cfg.package;
- is55 = mysql.mysqlVersion == "5.5";
-
- mysqldDir = if is55 then "${mysql}/bin" else "${mysql}/libexec";
+ atLeast55 = versionAtLeast mysql.mysqlVersion "5.5";
pidFile = "${cfg.pidDir}/mysqld.pid";
@@ -24,7 +22,7 @@ let
port = ${toString cfg.port}
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
- ${optionalString (cfg.replication.role == "slave" && !is55)
+ ${optionalString (cfg.replication.role == "slave" && !atLeast55)
''
master-host = ${cfg.replication.masterHost}
master-user = ${cfg.replication.masterUser}
@@ -75,7 +73,7 @@ in
};
pidDir = mkOption {
- default = "/var/run/mysql";
+ default = "/run/mysqld";
description = "Location of the file which stores the PID of the MySQL server";
};
@@ -180,15 +178,19 @@ in
mkdir -m 0700 -p ${cfg.pidDir}
chown -R ${cfg.user} ${cfg.pidDir}
+
+ # Make the socket directory
+ mkdir -m 0700 -p /run/mysqld
+ chown -R ${cfg.user} /run/mysqld
'';
- serviceConfig.ExecStart = "${mysqldDir}/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
+ serviceConfig.ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
postStart =
''
# Wait until the MySQL server is available for use
count=0
- while [ ! -e /tmp/mysql.sock ]
+ while [ ! -e /run/mysqld/mysqld.sock ]
do
if [ $count -eq 30 ]
then
@@ -222,7 +224,7 @@ in
fi
'') cfg.initialDatabases}
- ${optionalString (cfg.replication.role == "slave" && is55)
+ ${optionalString (cfg.replication.role == "slave" && atLeast55)
''
# Set up the replication master
diff --git a/nixos/modules/services/databases/neo4j.nix b/nixos/modules/services/databases/neo4j.nix
index 2ef49a95166..575034c93ab 100644
--- a/nixos/modules/services/databases/neo4j.nix
+++ b/nixos/modules/services/databases/neo4j.nix
@@ -19,7 +19,7 @@ let
org.neo4j.server.webadmin.rrdb.location=${cfg.dataDir}/data/rrd
org.neo4j.server.webadmin.data.uri=/db/data/
org.neo4j.server.webadmin.management.uri=/db/manage/
- org.neo4j.server.db.tuning.properties=${pkgs.neo4j}/share/neo4j/conf/neo4j.properties
+ org.neo4j.server.db.tuning.properties=${cfg.package}/share/neo4j/conf/neo4j.properties
org.neo4j.server.manage.console_engines=shell
${cfg.extraServerConfig}
'';
@@ -46,6 +46,12 @@ in {
type = types.uniq types.bool;
};
+ package = mkOption {
+ description = "Neo4j package to use.";
+ default = pkgs.neo4j;
+ type = types.package;
+ };
+
host = mkOption {
description = "Neo4j listen address.";
default = "127.0.0.1";
@@ -119,7 +125,7 @@ in {
after = [ "network-interfaces.target" ];
environment = { NEO4J_INSTANCE = cfg.dataDir; };
serviceConfig = {
- ExecStart = "${pkgs.neo4j}/bin/neo4j console";
+ ExecStart = "${cfg.package}/bin/neo4j console";
User = "neo4j";
PermissionsStartOnly = true;
};
diff --git a/nixos/modules/services/databases/openldap.nix b/nixos/modules/services/databases/openldap.nix
index eae4c114fc1..29bdb201752 100644
--- a/nixos/modules/services/databases/openldap.nix
+++ b/nixos/modules/services/databases/openldap.nix
@@ -20,23 +20,49 @@ in
services.openldap = {
enable = mkOption {
+ type = types.bool;
default = false;
description = "
Whether to enable the ldap server.
";
+ example = literalExample ''
+ openldap.enable = true;
+ openldap.extraConfig = '''
+ include ''${pkgs.openldap}/etc/openldap/schema/core.schema
+ include ''${pkgs.openldap}/etc/openldap/schema/cosine.schema
+ include ''${pkgs.openldap}/etc/openldap/schema/inetorgperson.schema
+ include ''${pkgs.openldap}/etc/openldap/schema/nis.schema
+
+ database bdb
+ suffix dc=example,dc=org
+ rootdn cn=admin,dc=example,dc=org
+ # NOTE: change after first start
+ rootpw secret
+ directory /var/db/openldap
+ ''';
+ '';
};
user = mkOption {
+ type = types.string;
default = "openldap";
description = "User account under which slapd runs.";
};
group = mkOption {
+ type = types.string;
default = "openldap";
description = "Group account under which slapd runs.";
};
+ dataDir = mkOption {
+ type = types.string;
+ default = "/var/db/openldap";
+ description = "The database directory.";
+ };
+
extraConfig = mkOption {
+ type = types.lines;
default = "";
description = "
sldapd.conf configuration
@@ -60,22 +86,22 @@ in
preStart = ''
mkdir -p /var/run/slapd
chown -R ${cfg.user}:${cfg.group} /var/run/slapd
- mkdir -p /var/db/openldap
- chown -R ${cfg.user}:${cfg.group} /var/db/openldap
+ mkdir -p ${cfg.dataDir}
+ chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}
'';
- serviceConfig.ExecStart = "${openldap}/libexec/slapd -u openldap -g openldap -d 0 -f ${configFile}";
+ serviceConfig.ExecStart = "${openldap}/libexec/slapd -u ${cfg.user} -g ${cfg.group} -d 0 -f ${configFile}";
};
- users.extraUsers = optionalAttrs (cfg.user == "openldap") (singleton
- { name = "openldap";
+ users.extraUsers.openldap =
+ { name = cfg.user;
group = cfg.group;
uid = config.ids.uids.openldap;
- });
+ };
- users.extraGroups = optionalAttrs (cfg.group == "openldap") (singleton
- { name = "openldap";
+ users.extraGroups.openldap =
+ { name = cfg.group;
gid = config.ids.gids.openldap;
- });
+ };
};
}
diff --git a/nixos/modules/services/databases/opentsdb.nix b/nixos/modules/services/databases/opentsdb.nix
new file mode 100644
index 00000000000..9c9738570e3
--- /dev/null
+++ b/nixos/modules/services/databases/opentsdb.nix
@@ -0,0 +1,100 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.opentsdb;
+
+ configFile = pkgs.writeText "opentsdb.conf" ''
+ tsd.core.auto_create_metrics = true
+ tsd.http.request.enable_chunked = true
+ '';
+
+in {
+
+ ###### interface
+
+ options = {
+
+ services.opentsdb = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to run OpenTSDB.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.opentsdb;
+ example = literalExample "pkgs.opentsdb";
+ description = ''
+ OpenTSDB package to use.
+ '';
+ };
+
+ user = mkOption {
+ type = types.string;
+ default = "opentsdb";
+ description = ''
+ User account under which OpenTSDB runs.
+ '';
+ };
+
+ group = mkOption {
+ type = types.string;
+ default = "opentsdb";
+ description = ''
+ Group account under which OpenTSDB runs.
+ '';
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 4242;
+ description = ''
+ Which port OpenTSDB listens on.
+ '';
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf config.services.opentsdb.enable {
+
+ systemd.services.opentsdb = {
+ description = "OpenTSDB Server";
+ wantedBy = [ "multi-user.target" ];
+ requires = [ "hbase.service" ];
+
+ environment.JAVA_HOME = "${pkgs.jre}";
+ path = [ pkgs.gnuplot ];
+
+ preStart =
+ ''
+ COMPRESSION=NONE HBASE_HOME=${config.services.hbase.package} ${cfg.package}/share/opentsdb/tools/create_table.sh
+ '';
+
+ serviceConfig = {
+ PermissionsStartOnly = true;
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = "${cfg.package}/bin/tsdb tsd --staticroot=${cfg.package}/share/opentsdb/static --cachedir=/tmp/opentsdb --port=${toString cfg.port} --config=${configFile}";
+ };
+ };
+
+ users.extraUsers.opentsdb = {
+ description = "OpenTSDB Server user";
+ group = "opentsdb";
+ uid = config.ids.uids.opentsdb;
+ };
+
+ users.extraGroups.opentsdb.gid = config.ids.gids.opentsdb;
+
+ };
+}
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 01c55479b2b..de14c56f797 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -225,14 +225,14 @@ in
# Wait for PostgreSQL to be ready to accept connections.
postStart =
''
- while ! psql postgres -c "" 2> /dev/null; do
+ while ! psql --port=${toString cfg.port} postgres -c "" 2> /dev/null; do
if ! kill -0 "$MAINPID"; then exit 1; fi
sleep 0.1
done
if test -e "${cfg.dataDir}/.first_startup"; then
${optionalString (cfg.initialScript != null) ''
- cat "${cfg.initialScript}" | psql postgres
+ cat "${cfg.initialScript}" | psql --port=${toString cfg.port} postgres
''}
rm -f "${cfg.dataDir}/.first_startup"
fi
diff --git a/nixos/modules/services/databases/postgresql.xml b/nixos/modules/services/databases/postgresql.xml
index e98b431bd60..a9802694295 100644
--- a/nixos/modules/services/databases/postgresql.xml
+++ b/nixos/modules/services/databases/postgresql.xml
@@ -24,11 +24,11 @@
services.postgresql.enable = true;
-services.postgresql.package = pkgs.postgresql93;
+services.postgresql.package = pkgs.postgresql94;
Note that you are required to specify the desired version of
-PostgreSQL (e.g. pkgs.postgresql93 ). Since
+PostgreSQL (e.g. pkgs.postgresql94 ). Since
upgrading your PostgreSQL version requires a database dump and reload
(see below), NixOS cannot provide a default value for
services.postgresql.package such as the most recent
diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix
index b91c389e90a..f2612d0b43b 100644
--- a/nixos/modules/services/databases/redis.nix
+++ b/nixos/modules/services/databases/redis.nix
@@ -201,7 +201,7 @@ in
environment.systemPackages = [ cfg.package ];
systemd.services.redis_init =
- { description = "Redis server initialisation";
+ { description = "Redis Server Initialisation";
wantedBy = [ "redis.service" ];
before = [ "redis.service" ];
@@ -216,7 +216,7 @@ in
};
systemd.services.redis =
- { description = "Redis server";
+ { description = "Redis Server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
diff --git a/nixos/modules/services/databases/virtuoso.nix b/nixos/modules/services/databases/virtuoso.nix
index f955cb74b6b..8a49e13395c 100644
--- a/nixos/modules/services/databases/virtuoso.nix
+++ b/nixos/modules/services/databases/virtuoso.nix
@@ -63,7 +63,7 @@ with lib;
jobs.virtuoso = {
name = "virtuoso";
- startOn = "filesystem";
+ startOn = "ip-up";
preStart = ''
mkdir -p ${stateDir}
diff --git a/nixos/modules/services/desktops/gnome3/gvfs.nix b/nixos/modules/services/desktops/gnome3/gvfs.nix
index 7e1382b161e..c4f41a6125c 100644
--- a/nixos/modules/services/desktops/gnome3/gvfs.nix
+++ b/nixos/modules/services/desktops/gnome3/gvfs.nix
@@ -1,6 +1,6 @@
# gvfs backends
-{ config, lib, ... }:
+{ config, lib, pkgs, ... }:
with lib;
@@ -37,6 +37,8 @@ in
services.dbus.packages = [ gnome3.gvfs ];
+ services.udev.packages = [ pkgs.libmtp ];
+
};
}
diff --git a/nixos/modules/services/desktops/profile-sync-daemon.nix b/nixos/modules/services/desktops/profile-sync-daemon.nix
new file mode 100644
index 00000000000..d66ecef2385
--- /dev/null
+++ b/nixos/modules/services/desktops/profile-sync-daemon.nix
@@ -0,0 +1,139 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.services.psd;
+
+ configFile = ''
+ ${optionalString (cfg.users != [ ]) ''
+ USERS="${concatStringsSep " " cfg.users}"
+ ''}
+
+ ${optionalString (cfg.browsers != [ ]) ''
+ BROWSERS="${concatStringsSep " " cfg.browsers}"
+ ''}
+
+ ${optionalString (cfg.volatile != "") "VOLATILE=${cfg.volatile}"}
+ ${optionalString (cfg.daemonFile != "") "DAEMON_FILE=${cfg.daemonFile}"}
+ '';
+
+in {
+
+ options.services.psd = with types; {
+ enable = mkOption {
+ type = bool;
+ default = false;
+ description = ''
+ Whether to enable the Profile Sync daemon.
+ '';
+ };
+
+ users = mkOption {
+ type = listOf str;
+ default = [ ];
+ example = [ "demo" ];
+ description = ''
+ A list of users whose browser profiles should be sync'd to tmpfs.
+ '';
+ };
+
+ browsers = mkOption {
+ type = listOf str;
+ default = [ ];
+ example = [ "chromium" "firefox" ];
+ description = ''
+ A list of browsers to sync. Available choices are:
+
+ chromium chromium-dev conkeror.mozdev.org epiphany firefox
+ firefox-trunk google-chrome google-chrome-beta google-chrome-unstable
+ heftig-aurora icecat luakit midori opera opera-developer opera-beta
+ qupzilla palemoon rekonq seamonkey
+
+ An empty list will enable all browsers.
+ '';
+ };
+
+ resyncTimer = mkOption {
+ type = str;
+ default = "1h";
+ example = "1h 30min";
+ description = ''
+ The amount of time to wait before syncing browser profiles back to the
+ disk.
+
+ Takes a systemd.unit time span. The time unit defaults to seconds if
+ omitted.
+ '';
+ };
+
+ volatile = mkOption {
+ type = str;
+ default = "/run/psd-profiles";
+ description = ''
+ The directory where browser profiles should reside(this should be
+ mounted as a tmpfs). Do not include a trailing backslash.
+ '';
+ };
+
+ daemonFile = mkOption {
+ type = str;
+ default = "/run/psd";
+ description = ''
+ Where the pid and backup configuration files will be stored.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd = {
+ services = {
+ psd = {
+ description = "Profile Sync daemon";
+ wants = [ "psd-resync.service" "local-fs.target" ];
+ wantedBy = [ "multi-user.target" ];
+ preStart = "mkdir -p ${cfg.volatile}";
+
+ path = with pkgs; [ glibc rsync gawk ];
+
+ unitConfig = {
+ RequiresMountsFor = [ "/home/" ];
+ };
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = "yes";
+ ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon sync";
+ ExecStop = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon unsync";
+ };
+ };
+
+ psd-resync = {
+ description = "Timed profile resync";
+ after = [ "psd.service" ];
+ wants = [ "psd-resync.timer" ];
+ partOf = [ "psd.service" ];
+
+ path = with pkgs; [ glibc rsync gawk ];
+
+ serviceConfig = {
+ Type = "oneshot";
+ ExecStart = "${pkgs.profile-sync-daemon}/bin/profile-sync-daemon resync";
+ };
+ };
+ };
+
+ timers.psd-resync = {
+ description = "Timer for profile sync daemon - ${cfg.resyncTimer}";
+ partOf = [ "psd-resync.service" "psd.service" ];
+
+ timerConfig = {
+ OnUnitActiveSec = "${cfg.resyncTimer}";
+ };
+ };
+ };
+
+ environment.etc."psd.conf".text = configFile;
+
+ };
+}
diff --git a/nixos/modules/services/games/minecraft-server.nix b/nixos/modules/services/games/minecraft-server.nix
index 4c734aefa46..d2c8af6de0c 100644
--- a/nixos/modules/services/games/minecraft-server.nix
+++ b/nixos/modules/services/games/minecraft-server.nix
@@ -8,6 +8,7 @@ in
{
options = {
services.minecraft-server = {
+
enable = mkOption {
type = types.bool;
default = false;
@@ -15,7 +16,23 @@ in
If enabled, start a Minecraft Server. The listening port for
the server is always 25565 . The server
data will be loaded from and saved to
- /var/lib/minecraft .
+ ${cfg.dataDir} .
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.path;
+ default = "/var/lib/minecraft";
+ description = ''
+ Directory to store minecraft database and other state/data files.
+ '';
+ };
+
+ openFirewall = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to open ports in the firewall (if enabled) for the server.
'';
};
@@ -30,7 +47,7 @@ in
config = mkIf cfg.enable {
users.extraUsers.minecraft = {
description = "Minecraft Server Service user";
- home = "/var/lib/minecraft";
+ home = cfg.dataDir;
createHome = true;
uid = config.ids.uids.minecraft;
};
@@ -43,9 +60,14 @@ in
serviceConfig.Restart = "always";
serviceConfig.User = "minecraft";
script = ''
- cd /var/lib/minecraft
+ cd ${cfg.dataDir}
exec ${pkgs.minecraft-server}/bin/minecraft-server ${cfg.jvmOpts}
'';
};
+
+ networking.firewall = mkIf cfg.openFirewall {
+ allowedUDPPorts = [ 25565 ];
+ allowedTCPPorts = [ 25565 ];
+ };
};
}
diff --git a/nixos/modules/services/games/minetest-server.nix b/nixos/modules/services/games/minetest-server.nix
new file mode 100644
index 00000000000..996e313386f
--- /dev/null
+++ b/nixos/modules/services/games/minetest-server.nix
@@ -0,0 +1,104 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.minetest-server;
+ flag = val: name: if val != null then "--${name} ${val} " else "";
+ flags = [
+ (flag cfg.gameId "gameid")
+ (flag cfg.world "world")
+ (flag cfg.configPath "config")
+ (flag cfg.logPath "logfile")
+ (flag cfg.port "port")
+ ];
+in
+{
+ options = {
+ services.minetest-server = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "If enabled, starts a Minetest Server.";
+ };
+
+ gameId = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Id of the game to use. To list available games run
+ `minetestserver --gameid list`.
+
+ If only one game exists, this option can be null.
+ '';
+ };
+
+ world = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Name of the world to use. To list available worlds run
+ `minetestserver --world list`.
+
+ If only one world exists, this option can be null.
+ '';
+ };
+
+ configPath = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Path to the config to use.
+
+ If set to null, the config of the running user will be used:
+ `~/.minetest/minetest.conf`.
+ '';
+ };
+
+ logPath = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ description = ''
+ Path to logfile for logging.
+
+ If set to null, logging will be output to stdout which means
+ all output will be catched by systemd.
+ '';
+ };
+
+ port = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Port number to bind to.
+
+ If set to null, the default 30000 will be used.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ users.extraUsers.minetest = {
+ description = "Minetest Server Service user";
+ home = "/var/lib/minetest";
+ createHome = true;
+ uid = config.ids.uids.minetest;
+ };
+
+ systemd.services.minetest-server = {
+ description = "Minetest Server Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ serviceConfig.Restart = "always";
+ serviceConfig.User = "minetest";
+
+ script = ''
+ cd /var/lib/minetest
+
+ exec ${pkgs.minetest}/bin/minetestserver ${concatStrings flags}
+ '';
+ };
+ };
+}
diff --git a/nixos/modules/services/hardware/80-net-name-slot.rules b/nixos/modules/services/hardware/80-net-setup-link.rules
similarity index 100%
rename from nixos/modules/services/hardware/80-net-name-slot.rules
rename to nixos/modules/services/hardware/80-net-setup-link.rules
diff --git a/nixos/modules/services/hardware/freefall.nix b/nixos/modules/services/hardware/freefall.nix
new file mode 100644
index 00000000000..6e6960bac49
--- /dev/null
+++ b/nixos/modules/services/hardware/freefall.nix
@@ -0,0 +1,62 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+{
+
+ ###### interface
+
+ options = with types; {
+
+ services.freefall = {
+
+ enable = mkOption {
+ default = false;
+ description = ''
+ Whether to protect HP/Dell laptop hard drives (not SSDs) in free fall.
+ '';
+ type = bool;
+ };
+
+ devices = mkOption {
+ default = [ "/dev/sda" ];
+ description = ''
+ Device paths to all internal spinning hard drives.
+ '';
+ type = listOf string;
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = let
+
+ cfg = config.services.freefall;
+
+ mkService = dev:
+ assert dev != "";
+ let dev' = utils.escapeSystemdPath dev; in
+ nameValuePair "freefall-${dev'}"
+ { description = "Free-fall protection for ${dev}";
+ after = [ "${dev'}.device" ];
+ wantedBy = [ "${dev'}.device" ];
+ path = [ pkgs.freefall ];
+ serviceConfig = {
+ ExecStart = "${pkgs.freefall}/bin/freefall ${dev}";
+ Restart = "on-failure";
+ Type = "forking";
+ };
+ };
+
+ in mkIf cfg.enable {
+
+ environment.systemPackages = [ pkgs.freefall ];
+
+ systemd.services = listToAttrs (map mkService cfg.devices);
+
+ };
+
+}
diff --git a/nixos/modules/services/hardware/pommed.nix b/nixos/modules/services/hardware/pommed.nix
index 04db46999b0..a24557b40ba 100644
--- a/nixos/modules/services/hardware/pommed.nix
+++ b/nixos/modules/services/hardware/pommed.nix
@@ -4,30 +4,34 @@ with lib;
{
- options.services.hardware.pommed = {
- enable = mkOption {
- default = false;
- description = ''
- Whether to use the pommed tool to handle Apple laptop keyboard hotkeys.
- '';
+ options = {
+
+ services.hardware.pommed = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to use the pommed tool to handle Apple laptop keyboard hotkeys.
+ '';
+ };
+
+ configFile = mkOption {
+ type = types.path;
+ description = ''
+ The path to the pommed.conf file.
+ '';
+ };
};
- configFile = mkOption {
- default = "${pkgs.pommed}/etc/pommed.conf";
- description = ''
- The contents of the pommed.conf file.
- '';
- };
};
config = mkIf config.services.hardware.pommed.enable {
environment.systemPackages = [ pkgs.polkit ];
- environment.etc = [
- { source = config.services.hardware.pommed.configFile;
- target = "pommed.conf";
- }
- ];
+ environment.etc."pommed.conf".source = config.services.hardware.pommed.configFile;
+
+ services.hardware.pommed.configFile = "${pkgs.pommed}/etc/pommed.conf";
services.dbus.packages = [ pkgs.pommed ];
diff --git a/nixos/modules/services/hardware/tcsd.nix b/nixos/modules/services/hardware/tcsd.nix
index d7f6c188feb..220b154bd97 100644
--- a/nixos/modules/services/hardware/tcsd.nix
+++ b/nixos/modules/services/hardware/tcsd.nix
@@ -128,12 +128,12 @@ in
users.extraUsers = optionalAttrs (cfg.user == "tss") (singleton
{ name = "tss";
group = "tss";
- uid = config.ids.uids.nginx;
+ uid = config.ids.uids.tss;
});
users.extraGroups = optionalAttrs (cfg.group == "tss") (singleton
{ name = "tss";
- gid = config.ids.gids.nginx;
+ gid = config.ids.gids.tss;
});
};
}
diff --git a/nixos/modules/services/hardware/thermald.nix b/nixos/modules/services/hardware/thermald.nix
index 5233794a20c..88c3f99aed4 100644
--- a/nixos/modules/services/hardware/thermald.nix
+++ b/nixos/modules/services/hardware/thermald.nix
@@ -19,6 +19,8 @@ in {
###### implementation
config = mkIf cfg.enable {
+ services.dbus.packages = [ pkgs.thermald ];
+
systemd.services.thermald = {
description = "Thermal Daemon Service";
wantedBy = [ "multi-user.target" ];
diff --git a/nixos/modules/services/hardware/tlp.nix b/nixos/modules/services/hardware/tlp.nix
new file mode 100644
index 00000000000..f221c82e2ed
--- /dev/null
+++ b/nixos/modules/services/hardware/tlp.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+cfg = config.services.tlp;
+
+tlp = pkgs.tlp.override { kmod = config.system.sbin.modprobe; };
+
+confFile = pkgs.writeText "tlp" (builtins.readFile "${tlp}/etc/default/tlp" + cfg.extraConfig);
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.tlp = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the TLP daemon.";
+ };
+
+ extraConfig = mkOption {
+ type = types.str;
+ default = "";
+ description = "Additional configuration variables for TLP";
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ systemd.services = {
+ tlp = {
+ description = "TLP system startup/shutdown";
+
+ after = [ "multi-user.target" ];
+ wantedBy = [ "multi-user.target" ];
+ before = [ "shutdown.target" ];
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "${tlp}/bin/tlp init start";
+ ExecStop = "${tlp}/bin/tlp init stop";
+ };
+ };
+
+ tlp-sleep = {
+ description = "TLP suspend/resume";
+
+ wantedBy = [ "sleep.target" ];
+ before = [ "sleep.target" ];
+
+ unitConfig = {
+ StopWhenUnneeded = true;
+ };
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "${tlp}/bin/tlp suspend";
+ ExecStop = "${tlp}/bin/tlp resume";
+ };
+ };
+ };
+
+ services.udev.packages = [ tlp ];
+
+ environment.etc = [{ source = confFile;
+ target = "default/tlp";
+ }
+ ] ++ optional tlp.enableRDW {
+ source = "${tlp}/etc/NetworkManager/dispatcher.d/99tlp-rdw-nm";
+ target = "NetworkManager/dispatcher.d/99tlp-rdw-nm";
+ };
+
+ environment.systemPackages = [ tlp ];
+
+ };
+
+}
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index 068d14217a2..50588e44958 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -28,9 +28,11 @@ let
# Perform substitutions in all udev rules files.
udevRules = stdenv.mkDerivation {
name = "udev-rules";
+ preferLocalBuild = true;
buildCommand = ''
mkdir -p $out
shopt -s nullglob
+ set +o pipefail
# Set a reasonable $PATH for programs called by udev rules.
echo 'ENV{PATH}="${udevPath}/bin:${udevPath}/sbin"' > $out/00-path.rules
@@ -87,7 +89,7 @@ let
done
${optionalString config.networking.usePredictableInterfaceNames ''
- cp ${./80-net-name-slot.rules} $out/80-net-name-slot.rules
+ cp ${./80-net-setup-link.rules} $out/80-net-setup-link.rules
''}
# If auto-configuration is disabled, then remove
@@ -168,7 +170,6 @@ in
hardware.firmware = mkOption {
type = types.listOf types.path;
default = [];
- example = [ "/root/my-firmware" ];
description = ''
List of directories containing firmware files. Such files
will be loaded automatically if the kernel asks for them
@@ -177,10 +178,10 @@ in
firmware file with the same name, the first path in the list
takes precedence. Note that you must rebuild your system if
you add files to any of these directories. For quick testing,
- put firmware files in /root/test-firmware and add that
- directory to the list.
- Note that you can also add firmware packages to this
- list as these are directories in the nix store.
+ put firmware files in /root/test-firmware
+ and add that directory to the list. Note that you can also
+ add firmware packages to this list as these are directories in
+ the nix store.
'';
apply = list: pkgs.buildEnv {
name = "firmware";
@@ -236,7 +237,10 @@ in
system.activationScripts.udevd =
''
- echo "" > /proc/sys/kernel/hotplug
+ # The deprecated hotplug uevent helper is not used anymore
+ if [ -e /proc/sys/kernel/hotplug ]; then
+ echo "" > /proc/sys/kernel/hotplug
+ fi
# Regenerate the hardware database /var/lib/udev/hwdb.bin
# whenever systemd changes.
@@ -244,6 +248,11 @@ in
echo "regenerating udev hardware database..."
${config.systemd.package}/bin/udevadm hwdb --update && ln -sfn ${config.systemd.package} /var/lib/udev/prev-systemd
fi
+
+ # Allow the kernel to find our firmware.
+ if [ -e /sys/module/firmware_class/parameters/path ]; then
+ echo -n "${config.hardware.firmware}" > /sys/module/firmware_class/parameters/path
+ fi
'';
systemd.services.systemd-udevd =
diff --git a/nixos/modules/services/logging/fluentd.nix b/nixos/modules/services/logging/fluentd.nix
new file mode 100644
index 00000000000..61eeec504e0
--- /dev/null
+++ b/nixos/modules/services/logging/fluentd.nix
@@ -0,0 +1,39 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.fluentd;
+in {
+ ###### interface
+
+ options = {
+
+ services.fluentd = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable fluentd.";
+ };
+
+ config = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Fluentd config.";
+ };
+ };
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.services.fluentd = with pkgs; {
+ description = "Fluentd Daemon";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.fluentd}/bin/fluentd -c ${pkgs.writeText "fluentd.conf" cfg.config}";
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix
index 6887ab1e805..0186452de95 100644
--- a/nixos/modules/services/logging/logrotate.nix
+++ b/nixos/modules/services/logging/logrotate.nix
@@ -21,6 +21,7 @@ in
config = mkOption {
default = "";
+ type = types.lines;
description = ''
The contents of the logrotate config file
'';
diff --git a/nixos/modules/services/logging/logstash.nix b/nixos/modules/services/logging/logstash.nix
index 802dd454878..117ee1c900f 100644
--- a/nixos/modules/services/logging/logstash.nix
+++ b/nixos/modules/services/logging/logstash.nix
@@ -4,6 +4,16 @@ with lib;
let
cfg = config.services.logstash;
+ pluginPath = lib.concatStringsSep ":" cfg.plugins;
+ havePluginPath = lib.length cfg.plugins > 0;
+ ops = lib.optionalString;
+ verbosityFlag = {
+ debug = "--debug";
+ info = "--verbose";
+ warn = ""; # intentionally empty
+ error = "--quiet";
+ fatal = "--silent";
+ }."${cfg.logLevel}";
in
@@ -11,20 +21,69 @@ in
###### interface
options = {
+
services.logstash = {
+
enable = mkOption {
+ type = types.bool;
default = false;
- description = "Enable logstash";
+ description = "Enable logstash.";
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.logstash;
+ example = literalExample "pkgs.logstash";
+ description = "Logstash package to use.";
+ };
+
+ plugins = mkOption {
+ type = types.listOf types.path;
+ default = [ ];
+ example = literalExample "[ pkgs.logstash-contrib ]";
+ description = "The paths to find other logstash plugins in.";
+ };
+
+ logLevel = mkOption {
+ type = types.enum [ "debug" "info" "warn" "error" "fatal" ];
+ default = "warn";
+ description = "Logging verbosity level.";
+ };
+
+ watchdogTimeout = mkOption {
+ type = types.int;
+ default = 10;
+ description = "Set watchdog timeout value in seconds.";
+ };
+
+ filterWorkers = mkOption {
+ type = types.int;
+ default = 1;
+ description = "The quantity of filter workers to run.";
};
enableWeb = mkOption {
+ type = types.bool;
default = false;
- description = "Enable logstash web interface";
+ description = "Enable the logstash web interface.";
+ };
+
+ address = mkOption {
+ type = types.str;
+ default = "0.0.0.0";
+ description = "Address on which to start webserver.";
+ };
+
+ port = mkOption {
+ type = types.str;
+ default = "9292";
+ description = "Port on which to start webserver.";
};
inputConfig = mkOption {
+ type = types.lines;
default = ''stdin { type => "example" }'';
- description = "Logstash input configuration";
+ description = "Logstash input configuration.";
example = ''
# Read from journal
pipe {
@@ -35,8 +94,9 @@ in
};
filterConfig = mkOption {
+ type = types.lines;
default = ''noop {}'';
- description = "logstash filter configuration";
+ description = "logstash filter configuration.";
example = ''
if [type] == "syslog" {
# Keep only relevant systemd fields
@@ -52,13 +112,15 @@ in
};
outputConfig = mkOption {
+ type = types.lines;
default = ''stdout { debug => true debug_format => "json"}'';
- description = "Logstash output configuration";
+ description = "Logstash output configuration.";
example = ''
redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
elasticsearch { embedded => true }
'';
};
+
};
};
@@ -71,19 +133,26 @@ in
wantedBy = [ "multi-user.target" ];
environment = { JAVA_HOME = jre; };
serviceConfig = {
- ExecStart = "${logstash}/bin/logstash agent -f ${writeText "logstash.conf" ''
- input {
- ${cfg.inputConfig}
- }
+ ExecStart =
+ "${cfg.package}/bin/logstash agent " +
+ "-w ${toString cfg.filterWorkers} " +
+ ops havePluginPath "--pluginpath ${pluginPath} " +
+ "${verbosityFlag} " +
+ "--watchdog-timeout ${toString cfg.watchdogTimeout} " +
+ "-f ${writeText "logstash.conf" ''
+ input {
+ ${cfg.inputConfig}
+ }
- filter {
- ${cfg.filterConfig}
- }
+ filter {
+ ${cfg.filterConfig}
+ }
- output {
- ${cfg.outputConfig}
- }
- ''} ${optionalString cfg.enableWeb "-- web"}";
+ output {
+ ${cfg.outputConfig}
+ }
+ ''} " +
+ ops cfg.enableWeb "-- web -a ${cfg.address} -p ${cfg.port}";
};
};
};
diff --git a/nixos/modules/services/logging/syslog-ng.nix b/nixos/modules/services/logging/syslog-ng.nix
index 0b3f0cabb00..2bf6d1ff790 100644
--- a/nixos/modules/services/logging/syslog-ng.nix
+++ b/nixos/modules/services/logging/syslog-ng.nix
@@ -7,8 +7,7 @@ let
cfg = config.services.syslog-ng;
syslogngConfig = pkgs.writeText "syslog-ng.conf" ''
- @version: 3.5
- @include "scl.conf"
+ ${cfg.configHeader}
${cfg.extraConfig}
'';
@@ -18,7 +17,7 @@ let
syslogngOptions = [
"--foreground"
- "--module-path=${concatStringsSep ":" (["${pkgs.syslogng}/lib/syslog-ng"] ++ cfg.extraModulePaths)}"
+ "--module-path=${concatStringsSep ":" (["${cfg.package}/lib/syslog-ng"] ++ cfg.extraModulePaths)}"
"--cfgfile=${syslogngConfig}"
"--control=${ctrlSocket}"
"--persist-file=${persistFile}"
@@ -37,13 +36,11 @@ in {
Whether to enable the syslog-ng daemon.
'';
};
- serviceName = mkOption {
- type = types.str;
- default = "syslog-ng";
+ package = mkOption {
+ type = types.package;
+ default = pkgs.syslogng;
description = ''
- The name of the systemd service that runs syslog-ng. Set this to
- syslog if you want journald to automatically
- forward all logs to syslog-ng.
+ The package providing syslog-ng binaries.
'';
};
extraModulePaths = mkOption {
@@ -65,19 +62,31 @@ in {
Configuration added to the end of syslog-ng.conf .
'';
};
+ configHeader = mkOption {
+ type = types.lines;
+ default = ''
+ @version: 3.6
+ @include "scl.conf"
+ '';
+ description = ''
+ The very first lines of the configuration file. Should usually contain
+ the syslog-ng version header.
+ '';
+ };
};
};
config = mkIf cfg.enable {
- systemd.services."${cfg.serviceName}" = {
- wantedBy = [ "multi-user.target" ];
+ systemd.services.syslog-ng = {
+ description = "syslog-ng daemon";
preStart = "mkdir -p /{var,run}/syslog-ng";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "multi-user.target" ]; # makes sure hostname etc is set
serviceConfig = {
Type = "notify";
- Sockets = "syslog.socket";
StandardOutput = "null";
Restart = "on-failure";
- ExecStart = "${pkgs.syslogng}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}";
+ ExecStart = "${cfg.package}/sbin/syslog-ng ${concatStringsSep " " syslogngOptions}";
};
};
};
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 1fb7102e7f3..50ff1b38db1 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -45,8 +45,6 @@ let
pop3_uidl_format = %08Xv%08Xu
'' + cfg.extraConfig;
- confFile = pkgs.writeText "dovecot.conf" dovecotConf;
-
in
{
@@ -88,6 +86,12 @@ in
description = "Additional entries to put verbatim into Dovecot's config file.";
};
+ configFile = mkOption {
+ default = null;
+ description = "Config file used for the whole dovecot configuration.";
+ apply = v: if v != null then v else pkgs.writeText "dovecot.conf" dovecotConf;
+ };
+
mailLocation = mkOption {
default = "maildir:/var/spool/mail/%u"; /* Same as inbox, as postfix */
example = "maildir:~/mail:INBOX=/var/spool/mail/%u";
@@ -144,10 +148,11 @@ in
gid = config.ids.gids.dovecot2;
};
- jobs.dovecot2 =
+ systemd.services.dovecot2 =
{ description = "Dovecot IMAP/POP3 server";
- startOn = "started networking";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
preStart =
''
@@ -155,7 +160,13 @@ in
${pkgs.coreutils}/bin/chown -R ${cfg.user}:${cfg.group} /var/run/dovecot2
'';
- exec = "${pkgs.dovecot}/sbin/dovecot -F -c ${confFile}";
+ serviceConfig = {
+ ExecStart = "${pkgs.dovecot}/sbin/dovecot -F -c ${cfg.configFile}";
+ Restart = "on-failure";
+ RestartSec = "1s";
+ StartLimitInterval = "1min";
+ };
+
};
environment.systemPackages = [ pkgs.dovecot ];
diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix
new file mode 100644
index 00000000000..e0890d96a88
--- /dev/null
+++ b/nixos/modules/services/mail/exim.nix
@@ -0,0 +1,111 @@
+{ config, lib, pkgs, ... }:
+
+let
+ inherit (lib) mkIf mkOption singleton types;
+ inherit (pkgs) coreutils exim;
+ cfg = config.services.exim;
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.exim = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the Exim mail transfer agent.";
+ };
+
+ config = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Verbatim Exim configuration. This should not contain exim_user,
+ exim_group, exim_path, or spool_directory.
+ '';
+ };
+
+ user = mkOption {
+ type = types.string;
+ default = "exim";
+ description = ''
+ User to use when no root privileges are required.
+ In particular, this applies when receiving messages and when doing
+ remote deliveries. (Local deliveries run as various non-root users,
+ typically as the owner of a local mailbox.) Specifying this value
+ as root is not supported.
+ '';
+ };
+
+ group = mkOption {
+ type = types.string;
+ default = "exim";
+ description = ''
+ Group to use when no root privileges are required.
+ '';
+ };
+
+ spoolDir = mkOption {
+ type = types.string;
+ default = "/var/spool/exim";
+ description = ''
+ Location of the spool directory of exim.
+ '';
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ environment = {
+ etc."exim.conf".text = ''
+ exim_user = ${cfg.user}
+ exim_group = ${cfg.group}
+ exim_path = /var/setuid-wrappers/exim
+ spool_directory = ${cfg.spoolDir}
+ ${cfg.config}
+ '';
+ systemPackages = [ exim ];
+ };
+
+ users.extraUsers = singleton {
+ name = cfg.user;
+ description = "Exim mail transfer agent user";
+ uid = config.ids.uids.exim;
+ group = cfg.group;
+ };
+
+ users.extraGroups = singleton {
+ name = cfg.group;
+ gid = config.ids.gids.exim;
+ };
+
+ security.setuidPrograms = [ "exim" ];
+
+ systemd.services.exim = {
+ description = "Exim Mail Daemon";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${exim}/bin/exim -bdf -q30m";
+ ExecReload = "${coreutils}/bin/kill -HUP $MAINPID";
+ };
+ preStart = ''
+ if ! test -d ${cfg.spoolDir}; then
+ ${coreutils}/bin/mkdir -p ${cfg.spoolDir}
+ ${coreutils}/bin/chown ${cfg.user}:${cfg.group} ${cfg.spoolDir}
+ fi
+ '';
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/mail/mlmmj.nix b/nixos/modules/services/mail/mlmmj.nix
index 637974f05cd..db3a266d011 100644
--- a/nixos/modules/services/mail/mlmmj.nix
+++ b/nixos/modules/services/mail/mlmmj.nix
@@ -90,7 +90,7 @@ in
enable = true;
recipientDelimiter= "+";
extraMasterConf = ''
- mlmmj unix - n n - - pipe flags=ORhu user=mlmmj argv=${pkgs.mlmmj}/bin/mlmmj-recieve -F -L ${spoolDir}/$nextHop
+ mlmmj unix - n n - - pipe flags=ORhu user=mlmmj argv=${pkgs.mlmmj}/bin/mlmmj-receive -F -L ${spoolDir}/$nextHop
'';
extraAliases = concatMapStrings (alias cfg.listDomain) cfg.mailLists;
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index 8f75bd8ab5d..b84c63e6421 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -96,9 +96,9 @@ let
# -o smtpd_sasl_auth_enable=yes
# -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
- pickup fifo n - n 60 1 pickup
+ pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
- qmgr fifo n - n 300 1 qmgr
+ qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
diff --git a/nixos/modules/services/misc/apache-kafka.nix b/nixos/modules/services/misc/apache-kafka.nix
new file mode 100644
index 00000000000..168615153fe
--- /dev/null
+++ b/nixos/modules/services/misc/apache-kafka.nix
@@ -0,0 +1,156 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.apache-kafka;
+
+ serverProperties =
+ if cfg.serverProperties != null then
+ cfg.serverProperties
+ else
+ ''
+ # Generated by nixos
+ broker.id=${toString cfg.brokerId}
+ port=${toString cfg.port}
+ host.name=${cfg.hostname}
+ log.dirs=${concatStringsSep "," cfg.logDirs}
+ zookeeper.connect=${cfg.zookeeper}
+ ${toString cfg.extraProperties}
+ '';
+
+ configDir = pkgs.buildEnv {
+ name = "apache-kafka-conf";
+ paths = [
+ (pkgs.writeTextDir "server.properties" serverProperties)
+ (pkgs.writeTextDir "log4j.properties" cfg.log4jProperties)
+ ];
+ };
+
+in {
+
+ options.services.apache-kafka = {
+ enable = mkOption {
+ description = "Whether to enable Apache Kafka.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ brokerId = mkOption {
+ description = "Broker ID.";
+ default = 0;
+ type = types.int;
+ };
+
+ port = mkOption {
+ description = "Port number the broker should listen on.";
+ default = 9092;
+ type = types.int;
+ };
+
+ hostname = mkOption {
+ description = "Hostname the broker should bind to.";
+ default = "localhost";
+ type = types.string;
+ };
+
+ logDirs = mkOption {
+ description = "Log file directories";
+ default = [ "/tmp/kafka-logs" ];
+ type = types.listOf types.path;
+ };
+
+ zookeeper = mkOption {
+ description = "Zookeeper connection string";
+ default = "localhost:2181";
+ type = types.string;
+ };
+
+ extraProperties = mkOption {
+ description = "Extra properties for server.properties.";
+ type = types.nullOr types.lines;
+ default = null;
+ };
+
+ serverProperties = mkOption {
+ description = ''
+ Complete server.properties content. Other server.properties config
+ options will be ignored if this option is used.
+ '';
+ type = types.nullOr types.lines;
+ default = null;
+ };
+
+ log4jProperties = mkOption {
+ description = "Kafka log4j property configuration.";
+ default = ''
+ log4j.rootLogger=INFO, stdout
+
+ log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+ log4j.appender.stdout.layout.ConversionPattern=[%d] %p %m (%c)%n
+ '';
+ type = types.lines;
+ };
+
+ jvmOptions = mkOption {
+ description = "Extra command line options for the JVM running Kafka.";
+ default = [
+ "-server"
+ "-Xmx1G"
+ "-Xms1G"
+ "-XX:+UseCompressedOops"
+ "-XX:+UseParNewGC"
+ "-XX:+UseConcMarkSweepGC"
+ "-XX:+CMSClassUnloadingEnabled"
+ "-XX:+CMSScavengeBeforeRemark"
+ "-XX:+DisableExplicitGC"
+ "-Djava.awt.headless=true"
+ "-Djava.net.preferIPv4Stack=true"
+ ];
+ type = types.listOf types.string;
+ example = [
+ "-Djava.net.preferIPv4Stack=true"
+ "-Dcom.sun.management.jmxremote"
+ "-Dcom.sun.management.jmxremote.local.only=true"
+ ];
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ environment.systemPackages = [pkgs.apacheKafka];
+
+ users.extraUsers = singleton {
+ name = "apache-kafka";
+ uid = config.ids.uids.apache-kafka;
+ description = "Apache Kafka daemon user";
+ home = head cfg.logDirs;
+ };
+
+ systemd.services.apache-kafka = {
+ description = "Apache Kafka Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.jre}/bin/java \
+ -cp "${pkgs.apacheKafka}/libs/*:${configDir}" \
+ ${toString cfg.jvmOptions} \
+ kafka.Kafka \
+ ${configDir}/server.properties
+ '';
+ User = "apache-kafka";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ mkdir -m 0700 -p ${concatStringsSep " " cfg.logDirs}
+ if [ "$(id -u)" = 0 ]; then
+ chown apache-kafka ${concatStringsSep " " cfg.logDirs};
+ fi
+ '';
+ };
+
+ };
+}
diff --git a/nixos/modules/services/misc/autofs.nix b/nixos/modules/services/misc/autofs.nix
index e645bd25a66..f4a1059d09f 100644
--- a/nixos/modules/services/misc/autofs.nix
+++ b/nixos/modules/services/misc/autofs.nix
@@ -84,7 +84,7 @@ in
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
- path = [ pkgs.nfsUtils pkgs.sshfsFuse ];
+ path = [ pkgs.nfs-utils pkgs.sshfsFuse ];
preStop =
''
diff --git a/nixos/modules/services/misc/canto-daemon.nix b/nixos/modules/services/misc/canto-daemon.nix
new file mode 100644
index 00000000000..db51a263aab
--- /dev/null
+++ b/nixos/modules/services/misc/canto-daemon.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+cfg = config.services.canto-daemon;
+
+in {
+
+##### interface
+
+ options = {
+
+ services.canto-daemon = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the canto RSS daemon.";
+ };
+ };
+
+ };
+
+##### implementation
+
+ config = mkIf cfg.enable {
+
+ systemd.user.services.canto-daemon = {
+ description = "Canto RSS Daemon";
+ after = [ "network.target" ];
+ wantedBy = [ "default.target" ];
+ serviceConfig.ExecStart = "${pkgs.canto-daemon}/bin/canto-daemon";
+ };
+ };
+
+}
diff --git a/nixos/modules/services/misc/cpuminer-cryptonight.nix b/nixos/modules/services/misc/cpuminer-cryptonight.nix
new file mode 100644
index 00000000000..f31526f8d10
--- /dev/null
+++ b/nixos/modules/services/misc/cpuminer-cryptonight.nix
@@ -0,0 +1,66 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.cpuminer-cryptonight;
+
+ json = builtins.toJSON (
+ cfg // {
+ enable = null;
+ threads =
+ if cfg.threads == 0 then null else toString cfg.threads;
+ }
+ );
+
+ confFile = builtins.toFile "cpuminer.json" json;
+in
+{
+
+ options = {
+
+ services.cpuminer-cryptonight = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable the cpuminer cryptonight miner.
+ '';
+ };
+ url = mkOption {
+ type = types.string;
+ description = "URL of mining server";
+ };
+ user = mkOption {
+ type = types.string;
+ description = "Username for mining server";
+ };
+ pass = mkOption {
+ type = types.string;
+ default = "x";
+ description = "Password for mining server";
+ };
+ threads = mkOption {
+ type = types.int;
+ default = 0;
+ description = "Number of miner threads, defaults to available processors";
+ };
+ };
+
+ };
+
+ config = mkIf config.services.cpuminer-cryptonight.enable {
+
+ systemd.services.cpuminer-cryptonight = {
+ description = "Cryptonight cpuminer";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.cpuminer-multi}/bin/minerd --syslog --config=${confFile}";
+ User = "nobody";
+ };
+ };
+
+ };
+
+}
\ No newline at end of file
diff --git a/nixos/modules/services/misc/defaultUnicornConfig.rb b/nixos/modules/services/misc/defaultUnicornConfig.rb
new file mode 100644
index 00000000000..81abaf336dc
--- /dev/null
+++ b/nixos/modules/services/misc/defaultUnicornConfig.rb
@@ -0,0 +1,206 @@
+# The following was taken from github.com/crohr/syslogger and is BSD
+# licensed.
+require 'syslog'
+require 'logger'
+require 'thread'
+
+class Syslogger
+
+ VERSION = "1.6.0"
+
+ attr_reader :level, :ident, :options, :facility, :max_octets
+ attr_accessor :formatter
+
+ MAPPING = {
+ Logger::DEBUG => Syslog::LOG_DEBUG,
+ Logger::INFO => Syslog::LOG_INFO,
+ Logger::WARN => Syslog::LOG_WARNING,
+ Logger::ERROR => Syslog::LOG_ERR,
+ Logger::FATAL => Syslog::LOG_CRIT,
+ Logger::UNKNOWN => Syslog::LOG_ALERT
+ }
+
+ #
+ # Initializes default options for the logger
+ # ident :: the name of your program [default=$0].
+ # options :: syslog options [default=Syslog::LOG_PID | Syslog::LOG_CONS ].
+ # Correct values are:
+ # LOG_CONS : writes the message on the console if an error occurs when sending the message;
+ # LOG_NDELAY : no delay before sending the message;
+ # LOG_PERROR : messages will also be written on STDERR;
+ # LOG_PID : adds the process number to the message (just after the program name)
+ # facility :: the syslog facility [default=nil] Correct values include:
+ # Syslog::LOG_DAEMON
+ # Syslog::LOG_USER
+ # Syslog::LOG_SYSLOG
+ # Syslog::LOG_LOCAL2
+ # Syslog::LOG_NEWS
+ # etc.
+ #
+ # Usage:
+ # logger = Syslogger.new("my_app", Syslog::LOG_PID | Syslog::LOG_CONS, Syslog::LOG_LOCAL0)
+ # logger.level = Logger::INFO # use Logger levels
+ # logger.warn "warning message"
+ # logger.debug "debug message"
+ #
+ def initialize(ident = $0, options = Syslog::LOG_PID | Syslog::LOG_CONS, facility = nil)
+ @ident = ident
+ @options = options || (Syslog::LOG_PID | Syslog::LOG_CONS)
+ @facility = facility
+ @level = Logger::INFO
+ @mutex = Mutex.new
+ @formatter = Logger::Formatter.new
+ end
+
+ %w{debug info warn error fatal unknown}.each do |logger_method|
+ # Accepting *args as message could be nil.
+ # Default params not supported in ruby 1.8.7
+ define_method logger_method.to_sym do |*args, &block|
+ return true if @level > Logger.const_get(logger_method.upcase)
+ message = args.first || block && block.call
+ add(Logger.const_get(logger_method.upcase), message)
+ end
+
+ unless logger_method == 'unknown'
+ define_method "#{logger_method}?".to_sym do
+ @level <= Logger.const_get(logger_method.upcase)
+ end
+ end
+ end
+
+ # Log a message at the Logger::INFO level. Useful for use with Rack::CommonLogger
+ def write(msg)
+ add(Logger::INFO, msg)
+ end
+
+ # Logs a message at the Logger::INFO level.
+ def <<(msg)
+ add(Logger::INFO, msg)
+ end
+
+ # Low level method to add a message.
+ # +severity+:: the level of the message. One of Logger::DEBUG, Logger::INFO, Logger::WARN, Logger::ERROR, Logger::FATAL, Logger::UNKNOWN
+ # +message+:: the message string.
+ # If nil, the method will call the block and use the result as the message string.
+ # If both are nil or no block is given, it will use the progname as per the behaviour of both the standard Ruby logger, and the Rails BufferedLogger.
+ # +progname+:: optionally, overwrite the program name that appears in the log message.
+ def add(severity, message = nil, progname = nil, &block)
+ if message.nil? && block.nil? && !progname.nil?
+ message, progname = progname, nil
+ end
+ progname ||= @ident
+
+ @mutex.synchronize do
+ Syslog.open(progname, @options, @facility) do |s|
+ s.mask = Syslog::LOG_UPTO(MAPPING[@level])
+ communication = clean(message || block && block.call)
+ if self.max_octets
+ buffer = "#{tags_text}"
+ communication.bytes do |byte|
+ buffer.concat(byte)
+ # if the last byte we added is potentially part of an escape, we'll go ahead and add another byte
+ if buffer.bytesize >= self.max_octets && !['%'.ord,'\\'.ord].include?(byte)
+ s.log(MAPPING[severity],buffer)
+ buffer = ""
+ end
+ end
+ s.log(MAPPING[severity],buffer) unless buffer.empty?
+ else
+ s.log(MAPPING[severity],"#{tags_text}#{communication}")
+ end
+ end
+ end
+ end
+
+ # Set the max octets of the messages written to the log
+ def max_octets=(max_octets)
+ @max_octets = max_octets
+ end
+
+ # Sets the minimum level for messages to be written in the log.
+ # +level+:: one of Logger::DEBUG , Logger::INFO , Logger::WARN , Logger::ERROR , Logger::FATAL , Logger::UNKNOWN
+ def level=(level)
+ level = Logger.const_get(level.to_s.upcase) if level.is_a?(Symbol)
+
+ unless level.is_a?(Fixnum)
+ raise ArgumentError.new("Invalid logger level `#{level.inspect}`")
+ end
+
+ @level = level
+ end
+
+ # Sets the ident string passed along to Syslog
+ def ident=(ident)
+ @ident = ident
+ end
+
+ # Tagging code borrowed from ActiveSupport gem
+ def tagged(*tags)
+ new_tags = push_tags(*tags)
+ yield self
+ ensure
+ pop_tags(new_tags.size)
+ end
+
+ def push_tags(*tags)
+ tags.flatten.reject{ |i| i.respond_to?(:empty?) ? i.empty? : !i }.tap do |new_tags|
+ current_tags.concat new_tags
+ end
+ end
+
+ def pop_tags(size = 1)
+ current_tags.pop size
+ end
+
+ def clear_tags!
+ current_tags.clear
+ end
+
+ protected
+
+ # Borrowed from SyslogLogger.
+ def clean(message)
+ message = message.to_s.dup
+ message.strip! # remove whitespace
+ message.gsub!(/\n/, '\\n') # escape newlines
+ message.gsub!(/%/, '%%') # syslog(3) freaks on % (printf)
+ message.gsub!(/\e\[[^m]*m/, '') # remove useless ansi color codes
+ message
+ end
+
+ private
+
+ def tags_text
+ tags = current_tags
+ if tags.any?
+ tags.collect { |tag| "[#{tag}] " }.join
+ end
+ end
+
+ def current_tags
+ Thread.current[:syslogger_tagged_logging_tags] ||= []
+ end
+end
+
+worker_processes 2
+working_directory ENV["GITLAB_PATH"]
+pid ENV["UNICORN_PATH"] + "/tmp/pids/unicorn.pid"
+
+listen ENV["UNICORN_PATH"] + "/tmp/sockets/gitlab.socket", :backlog => 1024
+listen "127.0.0.1:8080", :tcp_nopush => true
+
+timeout 60
+
+logger Syslogger.new
+
+preload_app true
+
+GC.respond_to?(:copy_on_write_friendly=) and
+ GC.copy_on_write_friendly = true
+
+check_client_connection false
+
+after_fork do |server, worker|
+ defined?(ActiveRecord::Base) and
+ ActiveRecord::Base.establish_connection
+end
diff --git a/nixos/modules/services/misc/disnix.nix b/nixos/modules/services/misc/disnix.nix
index 219c7ed9587..48bb9e4293e 100644
--- a/nixos/modules/services/misc/disnix.nix
+++ b/nixos/modules/services/misc/disnix.nix
@@ -132,7 +132,7 @@ in
restartIfChanged = false;
- path = [ pkgs.nix pkgs.disnix dysnomia ];
+ path = [ pkgs.nix pkgs.disnix dysnomia "/run/current-system/sw" ];
environment = {
HOME = "/root";
diff --git a/nixos/modules/services/misc/docker-registry.nix b/nixos/modules/services/misc/docker-registry.nix
new file mode 100644
index 00000000000..d25fd13a77d
--- /dev/null
+++ b/nixos/modules/services/misc/docker-registry.nix
@@ -0,0 +1,82 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.dockerRegistry;
+
+in {
+ ###### interface
+
+ options.services.dockerRegistry = {
+ enable = mkOption {
+ description = "Whether to enable docker registry server.";
+ default = false;
+ type = types.bool;
+ };
+
+ host = mkOption {
+ description = "Docker registry host or ip to bind to.";
+ default = "127.0.0.1";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Docker registry port to bind to.";
+ default = 5000;
+ type = types.int;
+ };
+
+ storagePath = mkOption {
+ type = types.path;
+ default = "/var/lib/docker/registry";
+ description = "Docker registry storage path.";
+ };
+
+ extraConfig = mkOption {
+ description = ''
+ Docker extra registry configuration. See
+
+ '';
+ default = {};
+ type = types.attrsOf types.str;
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.docker-registry = {
+ description = "Docker Container Registry";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ environment = {
+ REGISTRY_HOST = cfg.host;
+ REGISTRY_PORT = toString cfg.port;
+ GUNICORN_OPTS = "[--preload]"; # see https://github.com/docker/docker-registry#sqlalchemy
+ STORAGE_PATH = cfg.storagePath;
+ } // cfg.extraConfig;
+
+ serviceConfig = {
+ ExecStart = "${pkgs.pythonPackages.docker_registry}/bin/docker-registry";
+ User = "docker-registry";
+ Group = "docker";
+ PermissionsStartOnly = true;
+ };
+
+ preStart = ''
+ mkdir -p ${cfg.storagePath}
+ if [ "$(id -u)" = 0 ]; then
+ chown -R docker-registry:docker ${cfg.storagePath}
+ fi
+ '';
+ postStart = ''
+ until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.host}:${toString cfg.port}/'; do
+ sleep 1;
+ done
+ '';
+ };
+
+ users.extraGroups.docker.gid = mkDefault config.ids.gids.docker;
+ users.extraUsers.docker-registry.uid = config.ids.uids.docker-registry;
+ };
+}
diff --git a/nixos/modules/services/misc/etcd.nix b/nixos/modules/services/misc/etcd.nix
new file mode 100644
index 00000000000..284361a04d9
--- /dev/null
+++ b/nixos/modules/services/misc/etcd.nix
@@ -0,0 +1,144 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.etcd;
+
+in {
+
+ options.services.etcd = {
+ enable = mkOption {
+ description = "Whether to enable etcd.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ name = mkOption {
+ description = "Etcd unique node name.";
+ default = config.networking.hostName;
+ type = types.str;
+ };
+
+ advertiseClientUrls = mkOption {
+ description = "Etcd list of this member's client URLs to advertise to the rest of the cluster.";
+ default = cfg.listenClientUrls;
+ type = types.listOf types.str;
+ };
+
+ listenClientUrls = mkOption {
+ description = "Etcd list of URLs to listen on for client traffic.";
+ default = ["http://localhost:4001"];
+ type = types.listOf types.str;
+ };
+
+ listenPeerUrls = mkOption {
+ description = "Etcd list of URLs to listen on for peer traffic.";
+ default = ["http://localhost:7001"];
+ type = types.listOf types.str;
+ };
+
+ initialAdvertisePeerUrls = mkOption {
+ description = "Etcd list of this member's peer URLs to advertise to rest of the cluster.";
+ default = cfg.listenPeerUrls;
+ type = types.listOf types.str;
+ };
+
+ initialCluster = mkOption {
+ description = "Etcd initial cluster configuration for bootstrapping.";
+ default = ["${cfg.name}=http://localhost:7001"];
+ type = types.listOf types.str;
+ };
+
+ initialClusterState = mkOption {
+ description = "Etcd initial cluster configuration for bootstrapping.";
+ default = "new";
+ type = types.enum ["new" "existing"];
+ };
+
+ initialClusterToken = mkOption {
+ description = "Etcd initial cluster token for etcd cluster during bootstrap.";
+ default = "etcd-cluster";
+ type = types.str;
+ };
+
+ discovery = mkOption {
+ description = "Etcd discovery url";
+ default = "";
+ type = types.str;
+ };
+
+ extraConf = mkOption {
+ description = ''
+ Etcd extra configuration. See
+
+ '';
+ type = types.attrsOf types.str;
+ default = {};
+ example = literalExample ''
+ {
+ "CORS": "*",
+ "NAME": "default-name",
+ "MAX_RESULT_BUFFER": "1024",
+ "MAX_CLUSTER_SIZE": "9",
+ "MAX_RETRY_ATTEMPTS": "3"
+ }
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.path;
+ default = "/var/lib/etcd";
+ description = "Etcd data directory.";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.etcd = {
+ description = "Etcd Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+
+ environment = {
+ ETCD_NAME = cfg.name;
+ ETCD_DISCOVERY = cfg.discovery;
+ ETCD_DATA_DIR = cfg.dataDir;
+ ETCD_ADVERTISE_CLIENT_URLS = concatStringsSep "," cfg.advertiseClientUrls;
+ ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls;
+ ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls;
+ ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls;
+ } // (optionalAttrs (cfg.discovery == ""){
+ ETCD_INITIAL_CLUSTER = concatStringsSep "," cfg.initialCluster;
+ ETCD_INITIAL_CLUSTER_STATE = cfg.initialClusterState;
+ ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken;
+ }) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf);
+
+ serviceConfig = {
+ ExecStart = "${pkgs.etcd}/bin/etcd";
+ User = "etcd";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ mkdir -m 0700 -p ${cfg.dataDir}
+ if [ "$(id -u)" = 0 ]; then chown etcd ${cfg.dataDir}; fi
+ '';
+ postStart = ''
+ until ${pkgs.etcdctl}/bin/etcdctl set /nixos/state 'up'; do
+ sleep 1;
+ done
+ until ${pkgs.etcdctl}/bin/etcdctl get /nixos/state | grep up; do
+ sleep 1;
+ done
+ '';
+ };
+
+ environment.systemPackages = [ pkgs.etcdctl ];
+
+ users.extraUsers = singleton {
+ name = "etcd";
+ uid = config.ids.uids.etcd;
+ description = "Etcd daemon user";
+ home = cfg.dataDir;
+ };
+ };
+}
diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix
new file mode 100644
index 00000000000..4505c5ceb84
--- /dev/null
+++ b/nixos/modules/services/misc/gitlab.nix
@@ -0,0 +1,300 @@
+{ config, lib, pkgs, ... }:
+
+# TODO: support non-postgresql
+
+with lib;
+
+let
+ cfg = config.services.gitlab;
+
+ ruby = pkgs.gitlab.ruby;
+ bundler = pkgs.bundler;
+
+ gemHome = "${pkgs.gitlab.env}/${ruby.gemPath}";
+
+ databaseYml = ''
+ production:
+ adapter: postgresql
+ database: ${cfg.databaseName}
+ host: ${cfg.databaseHost}
+ password: ${cfg.databasePassword}
+ username: ${cfg.databaseUsername}
+ encoding: utf8
+ '';
+ gitlabShellYml = ''
+ user: gitlab
+ gitlab_url: "http://${cfg.host}:${toString cfg.port}/"
+ http_settings:
+ self_signed_cert: false
+ repos_path: "${cfg.stateDir}/repositories"
+ log_file: "${cfg.stateDir}/log/gitlab-shell.log"
+ redis:
+ bin: ${pkgs.redis}/bin/redis-cli
+ host: 127.0.0.1
+ port: 6379
+ database: 0
+ namespace: resque:gitlab
+ '';
+
+ unicornConfig = builtins.readFile ./defaultUnicornConfig.rb;
+
+ gitlab-runner = pkgs.stdenv.mkDerivation rec {
+ name = "gitlab-runner";
+ buildInputs = [ pkgs.gitlab pkgs.bundler pkgs.makeWrapper ];
+ phases = "installPhase fixupPhase";
+ buildPhase = "";
+ installPhase = ''
+ mkdir -p $out/bin
+ makeWrapper ${bundler}/bin/bundle $out/bin/gitlab-runner\
+ --set RAKEOPT '"-f ${pkgs.gitlab}/share/gitlab/Rakefile"'\
+ --set GEM_HOME '${gemHome}'\
+ --set UNICORN_PATH "${cfg.stateDir}/"\
+ --set GITLAB_PATH "${pkgs.gitlab}/share/gitlab/"\
+ --set GITLAB_APPLICATION_LOG_PATH "${cfg.stateDir}/log/application.log"\
+ --set GITLAB_SATELLITES_PATH "${cfg.stateDir}/satellites"\
+ --set GITLAB_SHELL_PATH "${pkgs.gitlab-shell}"\
+ --set GITLAB_REPOSITORIES_PATH "${cfg.stateDir}/repositories"\
+ --set GITLAB_SHELL_HOOKS_PATH "${cfg.stateDir}/shell/hooks"\
+ --set BUNDLE_GEMFILE "${pkgs.gitlab}/share/gitlab/Gemfile"\
+ --set GITLAB_EMAIL_FROM "${cfg.emailFrom}"\
+ --set GITLAB_SHELL_CONFIG_PATH "${cfg.stateDir}/shell/config.yml"\
+ --set GITLAB_SHELL_SECRET_PATH "${cfg.stateDir}/config/gitlab_shell_secret"\
+ --set GITLAB_HOST "${cfg.host}"\
+ --set GITLAB_PORT "${toString cfg.port}"\
+ --set GITLAB_BACKUP_PATH "${cfg.backupPath}"\
+ --set RAILS_ENV "production"
+ '';
+ };
+
+in {
+
+ options = {
+ services.gitlab = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the gitlab service.
+ '';
+ };
+
+ satelliteDir = mkOption {
+ type = types.str;
+ default = "/var/gitlab/git-satellites";
+ description = "Gitlab directory to store checked out git trees requires for operation.";
+ };
+
+ stateDir = mkOption {
+ type = types.str;
+ default = "/var/gitlab/state";
+ description = "Gitlab state directory, logs are stored here.";
+ };
+
+ backupPath = mkOption {
+ type = types.str;
+ default = cfg.stateDir + "/backup";
+ description = "Gitlab path for backups.";
+ };
+
+ databaseHost = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = "Gitlab database hostname.";
+ };
+
+ databasePassword = mkOption {
+ type = types.str;
+ default = "";
+ description = "Gitlab database user password.";
+ };
+
+ databaseName = mkOption {
+ type = types.str;
+ default = "gitlab";
+ description = "Gitlab database name.";
+ };
+
+ databaseUsername = mkOption {
+ type = types.str;
+ default = "gitlab";
+ description = "Gitlab database user.";
+ };
+
+ emailFrom = mkOption {
+ type = types.str;
+ default = "example@example.org";
+ description = "The source address for emails sent by gitlab.";
+ };
+
+ host = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ description = "Gitlab host name. Used e.g. for copy-paste URLs.";
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 8080;
+ description = "Gitlab server listening port.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ environment.systemPackages = [ gitlab-runner pkgs.gitlab-shell ];
+
+ assertions = [
+ { assertion = cfg.databasePassword != "";
+ message = "databasePassword must be set";
+ }
+ ];
+
+ # Redis is required for the sidekiq queue runner.
+ services.redis.enable = mkDefault true;
+ # We use postgres as the main data store.
+ services.postgresql.enable = mkDefault true;
+ services.postgresql.package = mkDefault pkgs.postgresql;
+ # Use postfix to send out mails.
+ services.postfix.enable = mkDefault true;
+
+ users.extraUsers = [
+ { name = "gitlab";
+ group = "gitlab";
+ home = "${cfg.stateDir}/home";
+ shell = "${pkgs.bash}/bin/bash";
+ uid = config.ids.uids.gitlab;
+ } ];
+
+ users.extraGroups = [
+ { name = "gitlab";
+ gid = config.ids.gids.gitlab;
+ } ];
+
+ systemd.services.gitlab-sidekiq = {
+ after = [ "network.target" "redis.service" ];
+ wantedBy = [ "multi-user.target" ];
+ environment.HOME = "${cfg.stateDir}/home";
+ environment.GEM_HOME = gemHome;
+ environment.UNICORN_PATH = "${cfg.stateDir}/";
+ environment.GITLAB_PATH = "${pkgs.gitlab}/share/gitlab/";
+ environment.GITLAB_APPLICATION_LOG_PATH = "${cfg.stateDir}/log/application.log";
+ environment.GITLAB_SATELLITES_PATH = "${cfg.stateDir}/satellites";
+ environment.GITLAB_SHELL_PATH = "${pkgs.gitlab-shell}";
+ environment.GITLAB_REPOSITORIES_PATH = "${cfg.stateDir}/repositories";
+ environment.GITLAB_SHELL_HOOKS_PATH = "${cfg.stateDir}/shell/hooks";
+ environment.BUNDLE_GEMFILE = "${pkgs.gitlab}/share/gitlab/Gemfile";
+ environment.GITLAB_EMAIL_FROM = "${cfg.emailFrom}";
+ environment.GITLAB_SHELL_CONFIG_PATH = "${cfg.stateDir}/shell/config.yml";
+ environment.GITLAB_SHELL_SECRET_PATH = "${cfg.stateDir}/config/gitlab_shell_secret";
+ environment.GITLAB_HOST = "${cfg.host}";
+ environment.GITLAB_PORT = "${toString cfg.port}";
+ environment.GITLAB_DATABASE_HOST = "${cfg.databaseHost}";
+ environment.GITLAB_DATABASE_PASSWORD = "${cfg.databasePassword}";
+ environment.RAILS_ENV = "production";
+ path = with pkgs; [
+ config.services.postgresql.package
+ gitAndTools.git
+ ruby
+ openssh
+ nodejs
+ ];
+ serviceConfig = {
+ Type = "simple";
+ User = "gitlab";
+ Group = "gitlab";
+ TimeoutSec = "300";
+ WorkingDirectory = "${pkgs.gitlab}/share/gitlab";
+ ExecStart="${bundler}/bin/bundle exec \"sidekiq -q post_receive -q mailer -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.stateDir}/tmp/sidekiq.pid\"";
+ };
+ };
+
+ systemd.services.gitlab = {
+ after = [ "network.target" "postgresql.service" "redis.service" ];
+ wantedBy = [ "multi-user.target" ];
+ environment.HOME = "${cfg.stateDir}/home";
+ environment.GEM_HOME = gemHome;
+ environment.UNICORN_PATH = "${cfg.stateDir}/";
+ environment.GITLAB_PATH = "${pkgs.gitlab}/share/gitlab/";
+ environment.GITLAB_APPLICATION_LOG_PATH = "${cfg.stateDir}/log/application.log";
+ environment.GITLAB_SATELLITES_PATH = "${cfg.stateDir}/satellites";
+ environment.GITLAB_SHELL_PATH = "${pkgs.gitlab-shell}";
+ environment.GITLAB_REPOSITORIES_PATH = "${cfg.stateDir}/repositories";
+ environment.GITLAB_SHELL_HOOKS_PATH = "${cfg.stateDir}/shell/hooks";
+ environment.BUNDLE_GEMFILE = "${pkgs.gitlab}/share/gitlab/Gemfile";
+ environment.GITLAB_EMAIL_FROM = "${cfg.emailFrom}";
+ environment.GITLAB_HOST = "${cfg.host}";
+ environment.GITLAB_PORT = "${toString cfg.port}";
+ environment.GITLAB_DATABASE_HOST = "${cfg.databaseHost}";
+ environment.GITLAB_DATABASE_PASSWORD = "${cfg.databasePassword}";
+ environment.RAILS_ENV = "production";
+ path = with pkgs; [
+ config.services.postgresql.package
+ gitAndTools.git
+ ruby
+ openssh
+ nodejs
+ ];
+ preStart = ''
+ # TODO: use env vars
+ mkdir -p ${cfg.stateDir}
+ mkdir -p ${cfg.stateDir}/log
+ mkdir -p ${cfg.stateDir}/satellites
+ mkdir -p ${cfg.stateDir}/repositories
+ mkdir -p ${cfg.stateDir}/shell/hooks
+ mkdir -p ${cfg.stateDir}/tmp/pids
+ mkdir -p ${cfg.stateDir}/tmp/sockets
+ rm -rf ${cfg.stateDir}/config
+ mkdir -p ${cfg.stateDir}/config
+ # TODO: What exactly is gitlab-shell doing with the secret?
+ head -c 20 /dev/urandom > ${cfg.stateDir}/config/gitlab_shell_secret
+ mkdir -p ${cfg.stateDir}/home/.ssh
+ touch ${cfg.stateDir}/home/.ssh/authorized_keys
+
+ cp -rf ${pkgs.gitlab}/share/gitlab/config ${cfg.stateDir}/
+ cp ${pkgs.gitlab}/share/gitlab/VERSION ${cfg.stateDir}/VERSION
+
+ ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.stateDir}/config/database.yml
+ ln -fs ${pkgs.writeText "unicorn.rb" unicornConfig} ${cfg.stateDir}/config/unicorn.rb
+
+ chown -R gitlab:gitlab ${cfg.stateDir}/
+ chmod -R 755 ${cfg.stateDir}/
+
+ if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
+ if ! test -e "${cfg.stateDir}/db-created"; then
+ psql postgres -c "CREATE ROLE gitlab WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'"
+ ${config.services.postgresql.package}/bin/createdb --owner gitlab gitlab || true
+ touch "${cfg.stateDir}/db-created"
+
+ # force=yes disables the manual-interaction yes/no prompt
+ # which breaks without an stdin.
+ force=yes ${bundler}/bin/bundle exec rake -f ${pkgs.gitlab}/share/gitlab/Rakefile gitlab:setup RAILS_ENV=production
+ fi
+ fi
+
+ # Install the shell required to push repositories
+ ln -fs ${pkgs.writeText "config.yml" gitlabShellYml} ${cfg.stateDir}/shell/config.yml
+ export GITLAB_SHELL_CONFIG_PATH=""${cfg.stateDir}/shell/config.yml
+ ${pkgs.gitlab-shell}/bin/install
+
+ # Change permissions in the last step because some of the
+ # intermediary scripts like to create directories as root.
+ chown -R gitlab:gitlab ${cfg.stateDir}/
+ chmod -R 755 ${cfg.stateDir}/
+ '';
+
+ serviceConfig = {
+ PermissionsStartOnly = true; # preStart must be run as root
+ Type = "simple";
+ User = "gitlab";
+ Group = "gitlab";
+ TimeoutSec = "300";
+ WorkingDirectory = "${pkgs.gitlab}/share/gitlab";
+ ExecStart="${bundler}/bin/bundle exec \"unicorn -c ${cfg.stateDir}/config/unicorn.rb -E production\"";
+ };
+
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/misc/gitolite.nix b/nixos/modules/services/misc/gitolite.nix
index 84435f92c11..16335c8aca7 100644
--- a/nixos/modules/services/misc/gitolite.nix
+++ b/nixos/modules/services/misc/gitolite.nix
@@ -5,6 +5,7 @@ with lib;
let
cfg = config.services.gitolite;
pubkeyFile = pkgs.writeText "gitolite-admin.pub" cfg.adminPubkey;
+ hooks = lib.concatMapStrings (hook: "${hook} ") cfg.commonHooks;
in
{
options = {
@@ -14,29 +15,53 @@ in
default = false;
description = ''
Enable gitolite management under the
- gitolite user. The Gitolite home
- directory is /var/lib/gitolite . After
+ gitolite user. After
switching to a configuration with Gitolite enabled, you can
then run git clone
gitolite@host:gitolite-admin.git to manage it further.
'';
};
+ dataDir = mkOption {
+ type = types.str;
+ default = "/var/lib/gitolite";
+ description = ''
+ Gitolite home directory (used to store all the repositories).
+ '';
+ };
+
adminPubkey = mkOption {
type = types.str;
description = ''
Initial administrative public key for Gitolite. This should
be an SSH Public Key. Note that this key will only be used
once, upon the first initialization of the Gitolite user.
+ The key string cannot have any line breaks in it.
+ '';
+ };
+
+ commonHooks = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = ''
+ A list of custom git hooks that get copied to ~/.gitolite/hooks/common .
+ '';
+ };
+
+ user = mkOption {
+ type = types.str;
+ default = "gitolite";
+ description = ''
+ Gitolite user account. This is the username of the gitolite endpoint.
'';
};
};
};
config = mkIf cfg.enable {
- users.extraUsers.gitolite = {
+ users.extraUsers.${cfg.user} = {
description = "Gitolite user";
- home = "/var/lib/gitolite";
+ home = cfg.dataDir;
createHome = true;
uid = config.ids.uids.gitolite;
useDefaultShell = true;
@@ -46,17 +71,21 @@ in
description = "Gitolite initialization";
wantedBy = [ "multi-user.target" ];
- serviceConfig.User = "gitolite";
+ serviceConfig.User = "${cfg.user}";
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.gitolite pkgs.git pkgs.perl pkgs.bash pkgs.openssh ];
script = ''
- cd /var/lib/gitolite
+ cd ${cfg.dataDir}
mkdir -p .gitolite/logs
if [ ! -d repositories ]; then
gitolite setup -pk ${pubkeyFile}
fi
+ if [ -n "${hooks}" ]; then
+ cp ${hooks} .gitolite/hooks/common/
+ chmod +x .gitolite/hooks/common/*
+ fi
gitolite setup # Upgrade if needed
'';
};
diff --git a/nixos/modules/services/misc/mediatomb.nix b/nixos/modules/services/misc/mediatomb.nix
new file mode 100644
index 00000000000..23227548039
--- /dev/null
+++ b/nixos/modules/services/misc/mediatomb.nix
@@ -0,0 +1,282 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ uid = config.ids.uids.mediatomb;
+ gid = config.ids.gids.mediatomb;
+ cfg = config.services.mediatomb;
+
+ mtConf = pkgs.writeText "config.xml" ''
+
+
+
+
+
+
+
+
+ ${cfg.serverName}
+ uuid:${cfg.uuid}
+ ${cfg.dataDir}
+ ${pkgs.mediatomb}/share/mediatomb/web
+
+
+ mediatomb.db
+
+
+
+ ${if cfg.dsmSupport then ''
+
+
+
+
+ redsonic.com
+ 105
+ '' else ""}
+ ${if cfg.tg100Support then ''
+ 101
+ '' else ""}
+
+
+ *
+
+ video
+
+
+
+
+
+
+ /nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/common.js
+ /nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/playlists.js
+
+ /nix/store/cngbzn39vidd6jm4wgzxfafqll74ybfa-mediatomb-0.12.1/share/mediatomb/js/import.js
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${if cfg.ps3Support then ''
+
+ '' else ""}
+ ${if cfg.dsmSupport then ''
+
+ '' else ""}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ audio/L16
+ no
+ yes
+ no
+
+
+
+
+ video/mpeg
+ yes
+ yes
+ yes
+
+
+
+
+
+
+ '';
+
+in {
+
+
+ ###### interface
+
+ options = {
+
+ services.mediatomb = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable the mediatomb DLNA server.
+ '';
+ };
+
+ serverName = mkOption {
+ type = types.string;
+ default = "mediatomb";
+ description = ''
+ How to identify the server on the network.
+ '';
+ };
+
+ ps3Support = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable ps3 specific tweaks.
+ WARNING: incompatible with DSM 320 support.
+ '';
+ };
+
+ dsmSupport = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable D-Link DSM 320 specific tweaks.
+ WARNING: incompatible with ps3 support.
+ '';
+ };
+
+ tg100Support = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Telegent TG100 specific tweaks.
+ '';
+ };
+
+ transcoding = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable transcoding.
+ '';
+ };
+
+ dataDir = mkOption {
+ type = types.path;
+ default = "/var/lib/mediatomb";
+ description = ''
+ The directory where mediatomb stores its state, data, etc.
+ '';
+ };
+
+ user = mkOption {
+ default = "mediatomb";
+ description = "User account under which mediatomb runs.";
+ };
+
+ group = mkOption {
+ default = "mediatomb";
+ description = "Group account under which mediatomb runs.";
+ };
+
+ port = mkOption {
+ default = 49152;
+ description = ''
+ The network port to listen on.
+ '';
+ };
+
+ uuid = mkOption {
+ default = "fdfc8a4e-a3ad-4c1d-b43d-a2eedb03a687";
+ description = ''
+ A unique (on your network) to identify the server by.
+ '';
+ };
+
+ customCfg = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Allow mediatomb to create and use its own config file inside ${cfg.dataDir}.
+ '';
+ };
+ };
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.services.mediatomb = {
+ description = "MediaTomb media Server";
+ after = [ "local-fs.target" "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.mediatomb ];
+ serviceConfig.ExecStart = "${pkgs.mediatomb}/bin/mediatomb -p ${toString cfg.port} ${if cfg.customCfg then "" else "-c ${mtConf}"} -m ${cfg.dataDir}";
+ serviceConfig.User = "${cfg.user}";
+ };
+
+ users.extraGroups = optionalAttrs (cfg.group == "mediatomb") (singleton {
+ name = "mediatomb";
+ gid = gid;
+ });
+
+ users.extraUsers = optionalAttrs (cfg.user == "mediatomb") (singleton {
+ name = "mediatomb";
+ isSystemUser = true;
+ group = cfg.group;
+ home = "${cfg.dataDir}";
+ createHome = true;
+ description = "Mediatomb DLNA Server User";
+ });
+
+ networking.firewall = {
+ allowedUDPPorts = [ 1900 cfg.port ];
+ allowedTCPPorts = [ cfg.port ];
+ };
+ };
+}
diff --git a/nixos/modules/services/misc/mesos-master.nix b/nixos/modules/services/misc/mesos-master.nix
new file mode 100644
index 00000000000..5609cf75bb5
--- /dev/null
+++ b/nixos/modules/services/misc/mesos-master.nix
@@ -0,0 +1,104 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.mesos.master;
+
+in {
+
+ options.services.mesos = {
+
+ master = {
+ enable = mkOption {
+ description = "Whether to enable the Mesos Master.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ port = mkOption {
+ description = "Mesos Master port";
+ default = 5050;
+ type = types.int;
+ };
+
+ zk = mkOption {
+ description = ''
+ ZooKeeper URL (used for leader election amongst masters).
+ May be one of:
+ zk://host1:port1,host2:port2,.../mesos
+ zk://username:password@host1:port1,host2:port2,.../mesos
+ '';
+ type = types.str;
+ };
+
+ workDir = mkOption {
+ description = "The Mesos work directory.";
+ default = "/var/lib/mesos/master";
+ type = types.str;
+ };
+
+ extraCmdLineOptions = mkOption {
+ description = ''
+ Extra command line options for Mesos Master.
+
+ See https://mesos.apache.org/documentation/latest/configuration/
+ '';
+ default = [ "" ];
+ type = types.listOf types.string;
+ example = [ "--credentials=VALUE" ];
+ };
+
+ quorum = mkOption {
+ description = ''
+ The size of the quorum of replicas when using 'replicated_log' based
+ registry. It is imperative to set this value to be a majority of
+ masters i.e., quorum > (number of masters)/2.
+
+ If 0 will fall back to --registry=in_memory.
+ '';
+ default = 0;
+ type = types.int;
+ };
+
+ logLevel = mkOption {
+ description = ''
+ The logging level used. Possible values:
+ 'INFO', 'WARNING', 'ERROR'
+ '';
+ default = "INFO";
+ type = types.str;
+ };
+
+ };
+
+
+ };
+
+
+ config = mkIf cfg.enable {
+ systemd.services.mesos-master = {
+ description = "Mesos Master";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.mesos}/bin/mesos-master \
+ --port=${toString cfg.port} \
+ --zk=${cfg.zk} \
+ ${if cfg.quorum == 0 then "--registry=in_memory" else "--registry=replicated_log --quorum=${toString cfg.quorum}"} \
+ --work_dir=${cfg.workDir} \
+ --logging_level=${cfg.logLevel} \
+ ${toString cfg.extraCmdLineOptions}
+ '';
+ Restart = "on-failure";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ mkdir -m 0700 -p ${cfg.workDir}
+ '';
+ };
+ };
+
+}
+
diff --git a/nixos/modules/services/misc/mesos-slave.nix b/nixos/modules/services/misc/mesos-slave.nix
new file mode 100644
index 00000000000..26fb3fdb00c
--- /dev/null
+++ b/nixos/modules/services/misc/mesos-slave.nix
@@ -0,0 +1,116 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.mesos.slave;
+
+ mkAttributes =
+ attrs: concatStringsSep ";" (mapAttrsToList
+ (k: v: "${k}:${v}")
+ (filterAttrs (k: v: v != null) attrs));
+ attribsArg = optionalString (cfg.attributes != {})
+ "--attributes=${mkAttributes cfg.attributes}";
+
+in {
+
+ options.services.mesos = {
+ slave = {
+ enable = mkOption {
+ description = "Whether to enable the Mesos Slave.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ port = mkOption {
+ description = "Mesos Slave port";
+ default = 5051;
+ type = types.int;
+ };
+
+ master = mkOption {
+ description = ''
+ May be one of:
+ zk://host1:port1,host2:port2,.../path
+ zk://username:password@host1:port1,host2:port2,.../path
+ '';
+ type = types.str;
+ };
+
+ withHadoop = mkOption {
+ description = "Add the HADOOP_HOME to the slave.";
+ default = false;
+ type = types.bool;
+ };
+
+ workDir = mkOption {
+ description = "The Mesos work directory.";
+ default = "/var/lib/mesos/slave";
+ type = types.str;
+ };
+
+ extraCmdLineOptions = mkOption {
+ description = ''
+ Extra command line options for Mesos Slave.
+
+ See https://mesos.apache.org/documentation/latest/configuration/
+ '';
+ default = [ "" ];
+ type = types.listOf types.string;
+ example = [ "--gc_delay=3days" ];
+ };
+
+ logLevel = mkOption {
+ description = ''
+ The logging level used. Possible values:
+ 'INFO', 'WARNING', 'ERROR'
+ '';
+ default = "INFO";
+ type = types.str;
+ };
+
+ attributes = mkOption {
+ description = ''
+ Machine attributes for the slave instance.
+
+ Use caution when changing this; you may need to manually reset slave
+ metadata before the slave can re-register.
+ '';
+ default = {};
+ type = types.attrsOf types.str;
+ example = { rack = "aa";
+ host = "aabc123";
+ os = "nixos"; };
+ };
+ };
+
+ };
+
+
+ config = mkIf cfg.enable {
+ systemd.services.mesos-slave = {
+ description = "Mesos Slave";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment.MESOS_CONTAINERIZERS = "docker,mesos";
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.mesos}/bin/mesos-slave \
+ --port=${toString cfg.port} \
+ --master=${cfg.master} \
+ ${optionalString cfg.withHadoop "--hadoop-home=${pkgs.hadoop}"} \
+ ${attribsArg} \
+ --work_dir=${cfg.workDir} \
+ --logging_level=${cfg.logLevel} \
+ --docker=${pkgs.docker}/libexec/docker/docker \
+ ${toString cfg.extraCmdLineOptions}
+ '';
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ mkdir -m 0700 -p ${cfg.workDir}
+ '';
+ };
+ };
+
+}
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index c98c0511b56..6d25fef4576 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -20,6 +20,8 @@ let
extraGroups = [ "nixbld" ];
};
+ nixbldUsers = map makeNixBuildUser (range 1 cfg.nrBuildUsers);
+
nixConf =
let
# If we're using a chroot for builds, then provide /bin/sh in
@@ -36,10 +38,15 @@ let
# /etc/nixos/configuration.nix. Do not edit it!
build-users-group = nixbld
build-max-jobs = ${toString (cfg.maxJobs)}
+ build-cores = ${toString (cfg.buildCores)}
build-use-chroot = ${if cfg.useChroot then "true" else "false"}
build-chroot-dirs = ${toString cfg.chrootDirs} /bin/sh=${sh} $(echo $extraPaths)
binary-caches = ${toString cfg.binaryCaches}
trusted-binary-caches = ${toString cfg.trustedBinaryCaches}
+ binary-cache-public-keys = ${toString cfg.binaryCachePublicKeys}
+ ${optionalString cfg.requireSignedBinaryCaches ''
+ signed-binary-caches = *
+ ''}
$extraOptions
END
'';
@@ -66,12 +73,26 @@ in
type = types.int;
default = 1;
example = 64;
- description = "
+ description = ''
This option defines the maximum number of jobs that Nix will try
to build in parallel. The default is 1. You should generally
set it to the number of CPUs in your system (e.g., 2 on an Athlon
64 X2).
- ";
+ '';
+ };
+
+ buildCores = mkOption {
+ type = types.int;
+ default = 1;
+ example = 64;
+ description = ''
+ This option defines the maximum number of concurrent tasks during
+ one build. It affects, e.g., -j option for make. The default is 1.
+ The special value 0 means that the builder should use all
+ available CPU cores in the system. Some builds may become
+ non-deterministic with this option; use with care! Packages will
+ only be affected if enableParallelBuilding is set for them.
+ '';
};
useChroot = mkOption {
@@ -179,17 +200,6 @@ in
'';
};
- proxy = mkOption {
- type = types.str;
- default = "";
- description = ''
- This option specifies the proxy to use for fetchurl. The real effect
- is just exporting http_proxy, https_proxy and ftp_proxy with that
- value.
- '';
- example = "http://127.0.0.1:3128";
- };
-
# Environment variables for running Nix.
envVars = mkOption {
type = types.attrs;
@@ -200,7 +210,6 @@ in
nrBuildUsers = mkOption {
type = types.int;
- default = 10;
description = ''
Number of nixbld user accounts created to
perform secure concurrent builds. If you receive an error
@@ -222,7 +231,7 @@ in
binaryCaches = mkOption {
type = types.listOf types.str;
- default = [ http://cache.nixos.org/ ];
+ default = [ https://cache.nixos.org/ ];
description = ''
List of binary cache URLs used to obtain pre-built binaries
of Nix packages.
@@ -241,6 +250,33 @@ in
'';
};
+ requireSignedBinaryCaches = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If enabled, Nix will only download binaries from binary
+ caches if they are cryptographically signed with any of the
+ keys listed in
+ nix.binaryCachePublicKeys . If disabled (the
+ default), signatures are neither required nor checked, so
+ it's strongly recommended that you use only trustworthy
+ caches and https to prevent man-in-the-middle attacks.
+ '';
+ };
+
+ binaryCachePublicKeys = mkOption {
+ type = types.listOf types.str;
+ example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
+ description = ''
+ List of public keys used to sign binary caches. If
+ nix.requireSignedBinaryCaches is enabled,
+ then Nix will use a binary from a binary cache if and only
+ if it is signed by any of the keys
+ listed here. By default, only the key for
+ cache.nixos.org is included.
+ '';
+ };
+
};
};
@@ -250,6 +286,8 @@ in
config = {
+ nix.binaryCachePublicKeys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
+
environment.etc."nix/nix.conf".source = nixConf;
# List of machines for distributed Nix builds in the format
@@ -278,7 +316,9 @@ in
{ path = [ nix pkgs.openssl pkgs.utillinux pkgs.openssh ]
++ optionals cfg.distributedBuilds [ pkgs.gzip ];
- environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; };
+ environment = cfg.envVars
+ // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; }
+ // config.networking.proxy.envVars;
serviceConfig =
{ Nice = cfg.daemonNiceLevel;
@@ -303,13 +343,6 @@ in
NIX_BUILD_HOOK = "${nix}/libexec/nix/build-remote.pl";
NIX_REMOTE_SYSTEMS = "/etc/nix/machines";
NIX_CURRENT_LOAD = "/run/nix/current-load";
- }
-
- # !!! These should not be defined here, but in some general proxy configuration module!
- // optionalAttrs (cfg.proxy != "") {
- http_proxy = cfg.proxy;
- https_proxy = cfg.proxy;
- ftp_proxy = cfg.proxy;
};
# Set up the environment variables for running Nix.
@@ -324,7 +357,11 @@ in
fi
'';
- users.extraUsers = map makeNixBuildUser (range 1 cfg.nrBuildUsers);
+ nix.nrBuildUsers = mkDefault (lib.max 10 cfg.maxJobs);
+
+ users.extraUsers = nixbldUsers;
+
+ services.xserver.displayManager.hiddenUsers = map ({ name, ... }: name) nixbldUsers;
system.activationScripts.nix = stringAfter [ "etc" "users" ]
''
@@ -342,9 +379,6 @@ in
/nix/var/nix/gcroots/per-user \
/nix/var/nix/profiles/per-user \
/nix/var/nix/gcroots/tmp
-
- ln -sf /nix/var/nix/profiles /nix/var/nix/gcroots/
- ln -sf /nix/var/nix/manifests /nix/var/nix/gcroots/
'';
};
diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix
index c0d7885280a..c570a01fb3b 100644
--- a/nixos/modules/services/misc/nixos-manual.nix
+++ b/nixos/modules/services/misc/nixos-manual.nix
@@ -3,7 +3,7 @@
# of the virtual consoles. The latter is useful for the installation
# CD.
-{ config, lib, pkgs, baseModules, ... } @ extraArgs:
+{ config, lib, pkgs, baseModules, ... }:
with lib;
@@ -14,11 +14,12 @@ let
versionModule =
{ system.nixosVersionSuffix = config.system.nixosVersionSuffix;
system.nixosRevision = config.system.nixosRevision;
+ nixpkgs.system = config.nixpkgs.system;
};
eval = evalModules {
modules = [ versionModule ] ++ baseModules;
- args = (removeAttrs extraArgs ["config" "options"]) // { modules = [ ]; };
+ args = (config._module.args) // { modules = [ ]; };
};
manual = import ../../../doc/manual {
diff --git a/nixos/modules/services/misc/parsoid.nix b/nixos/modules/services/misc/parsoid.nix
new file mode 100644
index 00000000000..0844190a549
--- /dev/null
+++ b/nixos/modules/services/misc/parsoid.nix
@@ -0,0 +1,100 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.parsoid;
+
+ conf = ''
+ exports.setup = function( parsoidConfig ) {
+ ${toString (mapAttrsToList (name: str: "parsoidConfig.setInterwiki('${name}', '${str}');") cfg.interwikis)}
+
+ parsoidConfig.serverInterface = "${cfg.interface}";
+ parsoidConfig.serverPort = ${toString cfg.port};
+
+ parsoidConfig.useSelser = true;
+
+ ${cfg.extraConfig}
+ };
+ '';
+
+ confFile = builtins.toFile "localsettings.js" conf;
+
+in
+{
+ ##### interface
+
+ options = {
+
+ services.parsoid = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable Parsoid -- bidirectional
+ wikitext parser.
+ '';
+ };
+
+ interwikis = mkOption {
+ type = types.attrsOf types.str;
+ example = { localhost = "http://localhost/api.php"; };
+ description = ''
+ Used MediaWiki API endpoints.
+ '';
+ };
+
+ workers = mkOption {
+ type = types.int;
+ default = 2;
+ description = ''
+ Number of Parsoid workers.
+ '';
+ };
+
+ interface = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ Interface to listen on.
+ '';
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 8000;
+ description = ''
+ Port to listen on.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration to add to parsoid configuration.
+ '';
+ };
+
+ };
+
+ };
+
+ ##### implementation
+
+ config = mkIf cfg.enable {
+
+ systemd.services.parsoid = {
+ description = "Bidirectional wikitext parser";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.nodePackages.parsoid}/lib/node_modules/parsoid/api/server.js -c ${confFile} -n ${toString cfg.workers}";
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/misc/phd.nix b/nixos/modules/services/misc/phd.nix
new file mode 100644
index 00000000000..e605ce5de16
--- /dev/null
+++ b/nixos/modules/services/misc/phd.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.phd;
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.phd = {
+
+ enable = mkOption {
+ default = false;
+ description = "
+ Enable daemons for phabricator.
+ ";
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ systemd.services.phd = {
+ path = [ pkgs.phabricator pkgs.php pkgs.mercurial pkgs.git pkgs.subversion ];
+
+ after = [ "httpd.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ ExecStart = "${pkgs.phabricator}/phabricator/bin/phd start";
+ ExecStop = "${pkgs.phabricator}/phabricator/bin/phd stop";
+ User = "wwwrun";
+ RestartSec = "30s";
+ Restart = "always";
+ StartLimitInterval = "1m";
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/misc/redmine.nix b/nixos/modules/services/misc/redmine.nix
new file mode 100644
index 00000000000..059cc18733b
--- /dev/null
+++ b/nixos/modules/services/misc/redmine.nix
@@ -0,0 +1,221 @@
+{ config, lib, pkgs, ... }:
+
+# TODO: support non-postgresql
+
+with lib;
+
+let
+ cfg = config.services.redmine;
+
+ ruby = pkgs.ruby;
+
+ databaseYml = ''
+ production:
+ adapter: postgresql
+ database: ${cfg.databaseName}
+ host: ${cfg.databaseHost}
+ password: ${cfg.databasePassword}
+ username: ${cfg.databaseUsername}
+ encoding: utf8
+ '';
+
+ configurationYml = ''
+ default:
+ # Absolute path to the directory where attachments are stored.
+ # The default is the 'files' directory in your Redmine instance.
+ # Your Redmine instance needs to have write permission on this
+ # directory.
+ # Examples:
+ # attachments_storage_path: /var/redmine/files
+ # attachments_storage_path: D:/redmine/files
+ attachments_storage_path: ${cfg.stateDir}/files
+
+ # Absolute path to the SCM commands errors (stderr) log file.
+ # The default is to log in the 'log' directory of your Redmine instance.
+ # Example:
+ # scm_stderr_log_file: /var/log/redmine_scm_stderr.log
+ scm_stderr_log_file: ${cfg.stateDir}/redmine_scm_stderr.log
+
+ ${cfg.extraConfig}
+ '';
+
+ unpackTheme = unpack "theme";
+ unpackPlugin = unpack "plugin";
+ unpack = id: (name: source:
+ pkgs.stdenv.mkDerivation {
+ name = "redmine-${id}-${name}";
+ buildInputs = [ pkgs.unzip ];
+ buildCommand = ''
+ mkdir -p $out
+ cd $out
+ unpackFile ${source}
+ '';
+ });
+
+in {
+
+ options = {
+ services.redmine = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the redmine service.
+ '';
+ };
+
+ stateDir = mkOption {
+ type = types.str;
+ default = "/var/redmine";
+ description = "The state directory, logs and plugins are stored here";
+ };
+
+ extraConfig = mkOption {
+ type = types.str;
+ default = "";
+ description = "Extra configuration in configuration.yml";
+ };
+
+ themes = mkOption {
+ type = types.attrsOf types.path;
+ default = {};
+ description = "Set of themes";
+ };
+
+ plugins = mkOption {
+ type = types.attrsOf types.path;
+ default = {};
+ description = "Set of plugins";
+ };
+
+ #databaseType = mkOption {
+ # type = types.str;
+ # default = "postgresql";
+ # description = "Type of database";
+ #};
+
+ databaseHost = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = "Database hostname";
+ };
+
+ databasePassword = mkOption {
+ type = types.str;
+ default = "";
+ description = "Database user password";
+ };
+
+ databaseName = mkOption {
+ type = types.str;
+ default = "redmine";
+ description = "Database name";
+ };
+
+ databaseUsername = mkOption {
+ type = types.str;
+ default = "redmine";
+ description = "Database user";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ assertions = [
+ { assertion = cfg.databasePassword != "";
+ message = "databasePassword must be set";
+ }
+ ];
+
+ users.extraUsers = [
+ { name = "redmine";
+ group = "redmine";
+ uid = config.ids.uids.redmine;
+ } ];
+
+ users.extraGroups = [
+ { name = "redmine";
+ gid = config.ids.gids.redmine;
+ } ];
+
+ systemd.services.redmine = {
+ after = [ "network.target" "postgresql.service" ];
+ wantedBy = [ "multi-user.target" ];
+ environment.RAILS_ENV = "production";
+ environment.RAILS_ETC = "${cfg.stateDir}/config";
+ environment.RAILS_LOG = "${cfg.stateDir}/log";
+ environment.RAILS_VAR = "${cfg.stateDir}/var";
+ environment.RAILS_CACHE = "${cfg.stateDir}/cache";
+ environment.RAILS_PLUGINS = "${cfg.stateDir}/plugins";
+ environment.RAILS_PUBLIC = "${cfg.stateDir}/public";
+ environment.RAILS_TMP = "${cfg.stateDir}/tmp";
+ environment.SCHEMA = "${cfg.stateDir}/cache/schema.db";
+ environment.HOME = "${pkgs.redmine}/share/redmine";
+ environment.REDMINE_LANG = "en";
+ environment.GEM_HOME = "${pkgs.redmine}/share/redmine/vendor/bundle/ruby/1.9.1";
+ environment.GEM_PATH = "${bundler}/${bundler.ruby.gemPath}";
+ path = with pkgs; [
+ imagemagickBig
+ subversion
+ mercurial
+ cvs
+ config.services.postgresql.package
+ bazaar
+ gitAndTools.git
+ # once we build binaries for darc enable it
+ #darcs
+ ];
+ preStart = ''
+ # TODO: use env vars
+ for i in plugins public/plugin_assets db files log config cache var/files tmp; do
+ mkdir -p ${cfg.stateDir}/$i
+ done
+
+ chown -R redmine:redmine ${cfg.stateDir}
+ chmod -R 755 ${cfg.stateDir}
+
+ rm -rf ${cfg.stateDir}/public/*
+ cp -R ${pkgs.redmine}/share/redmine/public/* ${cfg.stateDir}/public/
+ for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do
+ ln -fs $theme/* ${cfg.stateDir}/public/themes/
+ done
+
+ rm -rf ${cfg.stateDir}/plugins/*
+ for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do
+ ln -fs $plugin/* ${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}
+ done
+
+ ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.stateDir}/config/database.yml
+ ln -fs ${pkgs.writeText "configuration.yml" configurationYml} ${cfg.stateDir}/config/configuration.yml
+
+ if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then
+ if ! test -e "${cfg.stateDir}/db-created"; then
+ psql postgres -c "CREATE ROLE redmine WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'"
+ ${config.services.postgresql.package}/bin/createdb --owner redmine redmine || true
+ touch "${cfg.stateDir}/db-created"
+ fi
+ fi
+
+ cd ${pkgs.redmine}/share/redmine/
+ ${ruby}/bin/rake db:migrate
+ ${ruby}/bin/rake redmine:plugins:migrate
+ ${ruby}/bin/rake redmine:load_default_data
+ ${ruby}/bin/rake generate_secret_token
+ '';
+
+ serviceConfig = {
+ PermissionsStartOnly = true; # preStart must be run as root
+ Type = "simple";
+ User = "redmine";
+ Group = "redmine";
+ TimeoutSec = "300";
+ WorkingDirectory = "${pkgs.redmine}/share/redmine";
+ ExecStart="${ruby}/bin/ruby ${pkgs.redmine}/share/redmine/script/rails server webrick -e production -P ${cfg.stateDir}/redmine.pid";
+ };
+
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/misc/ripple-data-api.nix b/nixos/modules/services/misc/ripple-data-api.nix
new file mode 100644
index 00000000000..6e5ac7ab00b
--- /dev/null
+++ b/nixos/modules/services/misc/ripple-data-api.nix
@@ -0,0 +1,168 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.rippleDataApi;
+
+ deployment_env_config = builtins.toJSON {
+ production = {
+ port = toString cfg.port;
+ maxSockets = 150;
+ batchSize = 100;
+ startIndex = 32570;
+ rippleds = cfg.rippleds;
+ redis = {
+ enable = cfg.redis.enable;
+ host = cfg.redis.host;
+ port = cfg.redis.port;
+ options.auth_pass = null;
+ };
+ };
+ };
+
+ db_config = builtins.toJSON {
+ production = {
+ username = optional (cfg.couchdb.pass != "") cfg.couchdb.user;
+ password = optional (cfg.couchdb.pass != "") cfg.couchdb.pass;
+ host = cfg.couchdb.host;
+ port = cfg.couchdb.port;
+ database = cfg.couchdb.db;
+ protocol = "http";
+ };
+ };
+
+in {
+ options = {
+ services.rippleDataApi = {
+ enable = mkEnableOption "Whether to enable ripple data api.";
+
+ port = mkOption {
+ description = "Ripple data api port";
+ default = 5993;
+ type = types.int;
+ };
+
+ redis = {
+ enable = mkOption {
+ description = "Whether to enable caching of ripple data to redis.";
+ default = true;
+ type = types.bool;
+ };
+
+ host = mkOption {
+ description = "Ripple data api redis host.";
+ default = "localhost";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Ripple data api redis port.";
+ default = 5984;
+ type = types.int;
+ };
+ };
+
+ couchdb = {
+ host = mkOption {
+ description = "Ripple data api couchdb host.";
+ default = "localhost";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Ripple data api couchdb port.";
+ default = 5984;
+ type = types.int;
+ };
+
+ db = mkOption {
+ description = "Ripple data api couchdb database.";
+ default = "rippled";
+ type = types.str;
+ };
+
+ user = mkOption {
+ description = "Ripple data api couchdb username.";
+ default = "rippled";
+ type = types.str;
+ };
+
+ pass = mkOption {
+ description = "Ripple data api couchdb password.";
+ default = "";
+ type = types.str;
+ };
+
+ create = mkOption {
+ description = "Whether to create couchdb database needed by ripple data api.";
+ type = types.bool;
+ default = true;
+ };
+ };
+
+ rippleds = mkOption {
+ description = "List of rippleds to be used by ripple data api.";
+ default = [
+ "http://s_east.ripple.com:51234"
+ "http://s_west.ripple.com:51234"
+ ];
+ type = types.listOf types.str;
+ };
+ };
+ };
+
+ config = mkIf (cfg.enable) {
+ services.couchdb.enable = mkDefault true;
+ services.couchdb.bindAddress = mkDefault "0.0.0.0";
+ services.redis.enable = mkDefault true;
+
+ systemd.services.ripple-data-api = {
+ after = [ "couchdb.service" "redis.service" "ripple-data-api-importer.service" ];
+ wantedBy = [ "multi-user.target" ];
+
+ environment = {
+ NODE_ENV = "production";
+ DEPLOYMENT_ENVS_CONFIG = pkgs.writeText "deployment.environment.json" deployment_env_config;
+ DB_CONFIG = pkgs.writeText "db.config.json" db_config;
+ };
+
+ serviceConfig = {
+ ExecStart = "${pkgs.ripple-data-api}/bin/api";
+ User = "ripple-data-api";
+ };
+ };
+
+ systemd.services.ripple-data-importer = {
+ after = [ "couchdb.service" ];
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.curl ];
+
+ environment = {
+ NODE_ENV = "production";
+ DEPLOYMENT_ENVS_CONFIG = pkgs.writeText "deployment.environment.json" deployment_env_config;
+ DB_CONFIG = pkgs.writeText "db.config.json" db_config;
+ LOG_FILE = "/dev/null";
+ };
+
+ serviceConfig = {
+ ExecStart = "${pkgs.ripple-data-api}/bin/importer live debug2";
+ User = "ripple-data-api";
+ };
+
+ preStart = mkMerge [
+ (mkIf (cfg.couchdb.create) ''
+ HOST="http://${optionalString (cfg.couchdb.pass != "") "${cfg.couchdb.user}:${cfg.couchdb.pass}@"}${cfg.couchdb.host}:${toString cfg.couchdb.port}"
+ curl -X PUT $HOST/${cfg.couchdb.db} || true
+ '')
+ "${pkgs.ripple-data-api}/bin/update-views"
+ ];
+ };
+
+ users.extraUsers = singleton
+ { name = "ripple-data-api";
+ description = "Ripple data api user";
+ uid = config.ids.uids.ripple-data-api;
+ };
+ };
+}
diff --git a/nixos/modules/services/misc/rippled.nix b/nixos/modules/services/misc/rippled.nix
index 2c1fec9f6d7..85a1ed8ae9e 100644
--- a/nixos/modules/services/misc/rippled.nix
+++ b/nixos/modules/services/misc/rippled.nix
@@ -1,5 +1,3 @@
-# configuration building is commented out until better tested.
-
{ config, lib, pkgs, ... }:
with lib;
@@ -7,29 +5,189 @@ with lib;
let
cfg = config.services.rippled;
- rippledStateCfgFile = "/var/lib/rippled/rippled.cfg";
+ b2i = val: if val then "1" else "0";
+
+ dbCfg = db: ''
+ type=${db.type}
+ path=${db.path}
+ ${optionalString (db.compression != null) ("compression=${b2i db.compression}") }
+ ${optionalString (db.onlineDelete != null) ("online_delete=${toString db.onlineDelete}")}
+ ${optionalString (db.advisoryDelete != null) ("advisory_delete=${toString db.advisoryDelete}")}
+ ${db.extraOpts}
+ '';
rippledCfg = ''
+ [server]
+ ${concatMapStringsSep "\n" (n: "port_${n}") (attrNames cfg.ports)}
+
+ ${concatMapStrings (p: ''
+ [port_${p.name}]
+ ip=${p.ip}
+ port=${toString p.port}
+ protocol=${concatStringsSep "," p.protocol}
+ ${optionalString (p.user != "") "user=${p.user}"}
+ ${optionalString (p.password != "") "user=${p.password}"}
+ admin=${if p.admin then "allow" else "no"}
+ ${optionalString (p.ssl.key != null) "ssl_key=${p.ssl.key}"}
+ ${optionalString (p.ssl.cert != null) "ssl_cert=${p.ssl.cert}"}
+ ${optionalString (p.ssl.chain != null) "ssl_chain=${p.ssl.chain}"}
+ '') (attrValues cfg.ports)}
+
+ [database_path]
+ ${cfg.databasePath}
+
[node_db]
- type=HyperLevelDB
- path=/var/lib/rippled/db/hyperldb
+ ${dbCfg cfg.nodeDb}
- [debug_logfile]
- /var/log/rippled/debug.log
+ ${optionalString (cfg.tempDb != null) ''
+ [temp_db]
+ ${dbCfg cfg.tempDb}''}
- ''
- + optionalString (cfg.peerIp != null) ''
- [peer_ip]
- ${cfg.peerIp}
+ ${optionalString (cfg.importDb != null) ''
+ [import_db]
+ ${dbCfg cfg.importDb}''}
- [peer_port]
- ${toString cfg.peerPort}
+ [ips]
+ ${concatStringsSep "\n" cfg.ips}
- ''
- + cfg.extraConfig;
+ [ips_fixed]
+ ${concatStringsSep "\n" cfg.ipsFixed}
+
+ [validators]
+ ${concatStringsSep "\n" cfg.validators}
+
+ [node_size]
+ ${cfg.nodeSize}
+
+ [ledger_history]
+ ${toString cfg.ledgerHistory}
+
+ [fetch_depth]
+ ${toString cfg.fetchDepth}
+
+ [validation_quorum]
+ ${toString cfg.validationQuorum}
+
+ [sntp_servers]
+ ${concatStringsSep "\n" cfg.sntpServers}
+
+ [rpc_startup]
+ { "command": "log_level", "severity": "${cfg.logLevel}" }
+ '' + cfg.extraConfig;
+
+ portOptions = { name, ...}: {
+ options = {
+ name = mkOption {
+ internal = true;
+ default = name;
+ };
+
+ ip = mkOption {
+ default = "127.0.0.1";
+ description = "Ip where rippled listens.";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Port where rippled listens.";
+ type = types.int;
+ };
+
+ protocol = mkOption {
+ description = "Protocols expose by rippled.";
+ type = types.listOf (types.enum ["http" "https" "ws" "wss" "peer"]);
+ };
+
+ user = mkOption {
+ description = "When set, these credentials will be required on HTTP/S requests.";
+ type = types.str;
+ default = "";
+ };
+
+ password = mkOption {
+ description = "When set, these credentials will be required on HTTP/S requests.";
+ type = types.str;
+ default = "";
+ };
+
+ admin = mkOption {
+ description = "Controls whether or not administrative commands are allowed.";
+ type = types.bool;
+ default = false;
+ };
+
+ ssl = {
+ key = mkOption {
+ description = ''
+ Specifies the filename holding the SSL key in PEM format.
+ '';
+ default = null;
+ type = types.nullOr types.path;
+ };
+
+ cert = mkOption {
+ description = ''
+ Specifies the path to the SSL certificate file in PEM format.
+ This is not needed if the chain includes it.
+ '';
+ default = null;
+ type = types.nullOr types.path;
+ };
+
+ chain = mkOption {
+ description = ''
+ If you need a certificate chain, specify the path to the
+ certificate chain here. The chain may include the end certificate.
+ '';
+ default = null;
+ type = types.nullOr types.path;
+ };
+
+ };
+ };
+ };
+
+ dbOptions = {
+ type = mkOption {
+ description = "Rippled database type.";
+ type = types.enum ["rocksdb" "nudb" "sqlite"];
+ default = "rocksdb";
+ };
+
+ path = mkOption {
+ description = "Location to store the database.";
+ type = types.path;
+ default = cfg.databasePath;
+ };
+
+ compression = mkOption {
+ description = "Whether to enable snappy compression.";
+ type = types.nullOr types.bool;
+ default = null;
+ };
+
+ onlineDelete = mkOption {
+ description = "Enable automatic purging of older ledger information.";
+ type = types.addCheck (types.nullOr types.int) (v: v > 256);
+ default = cfg.ledgerHistory;
+ };
+
+ advisoryDelete = mkOption {
+ description = ''
+ If set, then require administrative RPC call "can_delete"
+ to enable online deletion of ledger records.
+ '';
+ type = types.nullOr types.bool;
+ default = null;
+ };
+
+ extraOpts = mkOption {
+ description = "Extra database options.";
+ type = types.lines;
+ default = "";
+ };
+ };
- rippledCfgFile = pkgs.writeText "rippled.cfg" rippledCfg;
-
in
{
@@ -37,236 +195,176 @@ in
###### interface
options = {
-
services.rippled = {
+ enable = mkEnableOption "Whether to enable rippled";
- enable = mkOption {
- default = false;
- description = "Whether to enable rippled";
+ package = mkOption {
+ description = "Which rippled package to use.";
+ type = types.package;
+ default = pkgs.rippled;
};
- #
- # Rippled has a simple configuration file layout that is easy to
- # build with nix. Many of the options are defined here but are
- # commented out until the code to append them to the config above
- # is written and they are tested.
- #
- # If you find a yourself implementing more options, please submit a
- # pull request.
- #
+ ports = mkOption {
+ description = "Ports exposed by rippled";
+ type = types.attrsOf types.optionSet;
+ options = [portOptions];
+ default = {
+ rpc = {
+ port = 5005;
+ admin = true;
+ protocol = ["http"];
+ };
+
+ peer = {
+ port = 51235;
+ ip = "0.0.0.0";
+ protocol = ["peer"];
+ };
+
+ ws_public = {
+ port = 5006;
+ ip = "0.0.0.0";
+ protocol = ["ws" "wss"];
+ };
+ };
+ };
+
+ nodeDb = mkOption {
+ description = "Rippled main database options.";
+ type = types.nullOr types.optionSet;
+ options = [dbOptions];
+ default = {
+ type = "rocksdb";
+ extraOpts = ''
+ open_files=2000
+ filter_bits=12
+ cache_mb=256
+ file_size_pb=8
+ file_size_mult=2;
+ '';
+ };
+ };
+
+ tempDb = mkOption {
+ description = "Rippled temporary database options.";
+ type = types.nullOr types.optionSet;
+ options = [dbOptions];
+ default = null;
+ };
+
+ importDb = mkOption {
+ description = "Settings for performing a one-time import.";
+ type = types.nullOr types.optionSet;
+ options = [dbOptions];
+ default = null;
+ };
+
+ nodeSize = mkOption {
+ description = ''
+ Rippled size of the node you are running.
+ "tiny", "small", "medium", "large", and "huge"
+ '';
+ type = types.enum ["tiny" "small" "medium" "large" "huge"];
+ default = "small";
+ };
- /*
ips = mkOption {
- default = [ "r.ripple.com 51235" ];
- example = [ "192.168.0.1" "192.168.0.1 3939" "r.ripple.com 51235" ];
description = ''
List of hostnames or ips where the Ripple protocol is served.
- For a starter list, you can either copy entries from:
+ For a starter list, you can either copy entries from:
https://ripple.com/ripple.txt or if you prefer you can let it
default to r.ripple.com 51235
- A port may optionally be specified after adding a space to the
- address. By convention, if known, IPs are listed in from most
+ A port may optionally be specified after adding a space to the
+ address. By convention, if known, IPs are listed in from most
to least trusted.
'';
+ type = types.listOf types.str;
+ default = ["r.ripple.com 51235"];
};
ipsFixed = mkOption {
- default = null;
- example = [ "192.168.0.1" "192.168.0.1 3939" "r.ripple.com 51235" ];
description = ''
- List of IP addresses or hostnames to which rippled should always
- attempt to maintain peer connections with. This is useful for
- manually forming private networks, for example to configure a
- validation server that connects to the Ripple network through a
+ List of IP addresses or hostnames to which rippled should always
+ attempt to maintain peer connections with. This is useful for
+ manually forming private networks, for example to configure a
+ validation server that connects to the Ripple network through a
public-facing server, or for building a set of cluster peers.
A port may optionally be specified after adding a space to the address
'';
- };
- */
-
- peerIp = mkOption {
- default = null;
- example = "0.0.0.0";
- description = ''
- IP address or domain to bind to allow external connections from peers.
- Defaults to not binding, which disallows external connections from peers.
- '';
+ type = types.listOf types.str;
+ default = [];
};
- peerPort = mkOption {
- default = 51235;
+ validators = mkOption {
description = ''
- If peerIp is supplied, corresponding port to bind to for peer connections.
+ List of nodes to always accept as validators. Nodes are specified by domain
+ or public key.
'';
+ type = types.listOf types.str;
+ default = [
+ "n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1"
+ "n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2"
+ "n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3"
+ "n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4"
+ "n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5"
+ ];
};
- /*
- peerPortProxy = mkOption {
- type = types.int;
- example = 51236;
+ databasePath = mkOption {
description = ''
- An optional, additional listening port number for peers. Incoming
- connections on this port will be required to provide a PROXY Protocol
- handshake, described in this document (external link):
-
- http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
-
- The PROXY Protocol is a popular method used by elastic load balancing
- service providers such as Amazon, to identify the true IP address and
- port number of external incoming connections.
-
- In addition to enabling this setting, it will also be required to
- use your provider-specific control panel or administrative web page
- to configure your server instance to receive PROXY Protocol handshakes,
- and also to restrict access to your instance to the Elastic Load Balancer.
+ Path to the ripple database.
'';
+ type = types.path;
+ default = "/var/lib/rippled/db";
};
- peerPrivate = mkOption {
- default = null;
- example = 0;
+ validationQuorum = mkOption {
description = ''
- 0: Request peers to broadcast your address. Normal outbound peer connections [default]
- 1: Request peers not broadcast your address. Only connect to configured peers.
- '';
- };
-
- peerSslCipherList = mkOption {
- default = null;
- example = "ALL:!LOW:!EXP:!MD5:@STRENGTH";
- description = ''
- A colon delimited string with the allowed SSL cipher modes for peer. The
- choices for for ciphers are defined by the OpenSSL API function
- SSL_CTX_set_cipher_list, documented here (external link):
-
- http://pic.dhe.ibm.com/infocenter/tpfhelp/current/index.jsp?topic=%2Fcom.ibm.ztpf-ztpfdf.doc_put.cur%2Fgtpc2%2Fcpp_ssl_ctx_set_cipher_list.html
-
- The default setting of "ALL:!LOW:!EXP:!MD5:@STRENGTH", which allows
- non-authenticated peer connections (they are, however, secure).
- '';
- };
-
- nodeSeed = mkOption {
- default = null;
- example = "RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE";
- description = ''
- This is used for clustering. To force a particular node seed or key, the
- key can be set here. The format is the same as the validation_seed field.
- To obtain a validation seed, use the rippled validation_create command.
- '';
- };
-
- clusterNodes = mkOption {
- default = null;
- example = [ "n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5" ];
- description = ''
- To extend full trust to other nodes, place their node public keys here.
- Generally, you should only do this for nodes under common administration.
- Node public keys start with an 'n'. To give a node a name for identification
- place a space after the public key and then the name.
- '';
- };
-
- sntpServers = mkOption {
- default = null;
- example = [ "time.nist.gov" "pool.ntp.org" ];
- description = ''
- IP address or domain of NTP servers to use for time synchronization.
- '';
- };
-
- # TODO: websocket options
-
- rpcAllowRemote = mkOption {
- default = false;
- description = ''
- false: Allow RPC connections only from 127.0.0.1. [default]
- true: Allow RPC connections from any IP.
- '';
- };
-
- rpcAdminAllow = mkOption {
- example = [ "10.0.0.4" ];
- description = ''
- List of IP addresses allowed to have admin access.
- '';
- };
-
- rpcAdminUser = mkOption {
- type = types.str;
- description = ''
- As a server, require this as the admin user to be specified. Also, require
- rpc_admin_user and rpc_admin_password to be checked for RPC admin functions.
- The request must specify these as the admin_user and admin_password in the
- request object.
- '';
- };
-
- rpcAdminPassword = mkOption {
- type = types.str;
- description = ''
- As a server, require this as the admin pasword to be specified. Also,
- require rpc_admin_user and rpc_admin_password to be checked for RPC admin
- functions. The request must specify these as the admin_user and
- admin_password in the request object.
- '';
- };
-
- rpcIp = mkOption {
- type = types.str;
- description = ''
- IP address or domain to bind to allow insecure RPC connections.
- Defaults to not binding, which disallows RPC connections.
+ The minimum number of trusted validations a ledger must have before
+ the server considers it fully validated.
'';
+ type = types.int;
+ default = 3;
};
- rpcPort = mkOption {
- type = types.int;
- description = ''
- If rpcIp is supplied, corresponding port to bind to for peer connections.
- '';
- };
-
- rpcUser = mkOption {
- type = types.str;
+ ledgerHistory = mkOption {
description = ''
- Require a this user to specified and require rpcPassword to
- be checked for RPC access via the rpcIp and rpcPort. The user and password
- must be specified via HTTP's basic authentication method.
- As a client, supply this to the server via HTTP's basic authentication
- method.
+ The number of past ledgers to acquire on server startup and the minimum
+ to maintain while running.
'';
+ type = types.either types.int (types.enum ["full"]);
+ default = 1296000; # 1 month
};
- rpcPassword = mkOption {
- type = types.str;
+ fetchDepth = mkOption {
description = ''
- Require a this password to specified and require rpc_user to
- be checked for RPC access via the rpcIp and rpcPort. The user and password
- must be specified via HTTP's basic authentication method.
- As a client, supply this to the server via HTTP's basic authentication
- method.
+ The number of past ledgers to serve to other peers that request historical
+ ledger data (or "full" for no limit).
'';
+ type = types.either types.int (types.enum ["full"]);
+ default = "full";
};
- rpcStartup = mkOption {
- example = [ ''"command" : "log_level"'' ''"partition" : "ripplecalc"'' ''"severity" : "trace"'' ];
- description = "List of RPC commands to run at startup.";
- };
-
- rpcSecure = mkOption {
- default = false;
+ sntpServers = mkOption {
description = ''
- false: Server certificates are not provided for RPC clients using SSL [default]
- true: Client RPC connections wil be provided with SSL certificates.
-
- Note that if rpc_secure is enabled, it will also be necessasry to configure the
- certificate file settings located in rpcSslCert, rpcSslChain, and rpcSslKey
+ IP address or domain of NTP servers to use for time synchronization.;
'';
+ type = types.listOf types.str;
+ default = [
+ "time.windows.com"
+ "time.apple.com"
+ "time.nist.gov"
+ "pool.ntp.org"
+ ];
+ };
+
+ logLevel = mkOption {
+ description = "Logging verbosity.";
+ type = types.enum ["debug" "error" "info"];
+ default = "error";
};
- */
extraConfig = mkOption {
default = "";
@@ -275,8 +373,11 @@ in
'';
};
+ config = mkOption {
+ internal = true;
+ default = pkgs.writeText "rippled.conf" rippledCfg;
+ };
};
-
};
@@ -288,27 +389,21 @@ in
{ name = "rippled";
description = "Ripple server user";
uid = config.ids.uids.rippled;
- home = "/var/lib/rippled";
+ home = cfg.databasePath;
+ createHome = true;
};
systemd.services.rippled = {
- path = [ pkgs.rippled ];
-
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
- ExecStart = "${pkgs.rippled}/bin/rippled --fg -q --conf ${rippledStateCfgFile}";
- WorkingDirectory = "/var/lib/rippled";
+ ExecStart = "${cfg.package}/bin/rippled --fg --conf ${cfg.config}";
+ User = "rippled";
};
};
- networking.firewall.allowedTCPPorts = mkIf (cfg.peerIp != null) [ cfg.peerPort ];
+ environment.systemPackages = [ cfg.package ];
- system.activationScripts.rippled = ''
- mkdir -p /var/{lib,log}/rippled
- chown -R rippled /var/{lib,log}/rippled
- ln -sf ${rippledCfgFile} ${rippledStateCfgFile}
- '';
};
}
diff --git a/nixos/modules/services/misc/synergy.nix b/nixos/modules/services/misc/synergy.nix
index 5338b25715c..054df965347 100644
--- a/nixos/modules/services/misc/synergy.nix
+++ b/nixos/modules/services/misc/synergy.nix
@@ -81,27 +81,26 @@ in
###### implementation
- config = {
-
- systemd.services."synergy-client" = {
- enable = cfgC.enable;
- after = [ "network.target" ];
- description = "Synergy client";
- wantedBy = optional cfgC.autoStart "multi-user.target";
- path = [ pkgs.synergy ];
- serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
- };
-
- systemd.services."synergy-server" = {
- enable = cfgS.enable;
- after = [ "network.target" ];
- description = "Synergy server";
- wantedBy = optional cfgS.autoStart "multi-user.target";
- path = [ pkgs.synergy ];
- serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }'';
- };
-
- };
+ config = mkMerge [
+ (mkIf cfgC.enable {
+ systemd.services."synergy-client" = {
+ after = [ "network.target" ];
+ description = "Synergy client";
+ wantedBy = optional cfgC.autoStart "multi-user.target";
+ path = [ pkgs.synergy ];
+ serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergyc -f ${optionalString (cfgC.screenName != "") "-n ${cfgC.screenName}"} ${cfgC.serverAddress}'';
+ };
+ })
+ (mkIf cfgS.enable {
+ systemd.services."synergy-server" = {
+ after = [ "network.target" ];
+ description = "Synergy server";
+ wantedBy = optional cfgS.autoStart "multi-user.target";
+ path = [ pkgs.synergy ];
+ serviceConfig.ExecStart = ''${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} -f ${optionalString (cfgS.address != "") "-a ${cfgS.address}"} ${optionalString (cfgS.screenName != "") "-n ${cfgS.screenName}" }'';
+ };
+ })
+ ];
}
diff --git a/nixos/modules/services/misc/uhub.nix b/nixos/modules/services/misc/uhub.nix
new file mode 100644
index 00000000000..15071202b9c
--- /dev/null
+++ b/nixos/modules/services/misc/uhub.nix
@@ -0,0 +1,186 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.uhub;
+
+ uhubPkg = pkgs.uhub.override { tlsSupport = cfg.enableTLS; };
+
+ pluginConfig = ""
+ + optionalString cfg.plugins.authSqlite.enable ''
+ plugin ${uhubPkg.mod_auth_sqlite}/mod_auth_sqlite.so "file=${cfg.plugins.authSqlite.file}"
+ ''
+ + optionalString cfg.plugins.logging.enable ''
+ plugin ${uhubPkg.mod_logging}/mod_logging.so ${if cfg.plugins.logging.syslog then "syslog=true" else "file=${cfg.plugins.logging.file}"}
+ ''
+ + optionalString cfg.plugins.welcome.enable ''
+ plugin ${uhubPkg.mod_welcome}/mod_welcome.so "motd=${pkgs.writeText "motd.txt" cfg.plugins.welcome.motd} rules=${pkgs.writeText "rules.txt" cfg.plugins.welcome.rules}"
+ ''
+ + optionalString cfg.plugins.history.enable ''
+ plugin ${uhubPkg.mod_chat_history}/mod_chat_history.so "history_max=${toString cfg.plugins.history.max} history_default=${toString cfg.plugins.history.default} history_connect=${toString cfg.plugins.history.connect}"
+ '';
+
+ uhubConfigFile = pkgs.writeText "uhub.conf" ''
+ file_acl=${pkgs.writeText "users.conf" cfg.aclConfig}
+ file_plugins=${pkgs.writeText "plugins.conf" pluginConfig}
+ server_bind_addr=${cfg.address}
+ server_port=${toString cfg.port}
+ ${lib.optionalString cfg.enableTLS "tls_enable=yes"}
+ ${cfg.hubConfig}
+ '';
+
+in
+
+{
+ options = {
+
+ services.uhub = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the uhub ADC hub.";
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 1511;
+ description = "TCP port to bind the hub to.";
+ };
+
+ address = mkOption {
+ type = types.string;
+ default = "any";
+ description = "Address to bind the hub to.";
+ };
+
+ enableTLS = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable TLS support.";
+ };
+
+ hubConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Contents of uhub configuration file.";
+ };
+
+ aclConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Contents of user ACL configuration file.";
+ };
+
+ plugins = {
+
+ authSqlite = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the Sqlite authentication database plugin";
+ };
+ file = mkOption {
+ type = types.string;
+ example = "/var/db/uhub-users";
+ description = "Path to user database. Use the uhub-passwd utility to create the database and add/remove users.";
+ };
+ };
+
+ logging = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the logging plugin.";
+ };
+ file = mkOption {
+ type = types.string;
+ default = "";
+ description = "Path of log file.";
+ };
+ syslog = mkOption {
+ type = types.bool;
+ default = false;
+ description = "If true then the system log is used instead of writing to file.";
+ };
+ };
+
+ welcome = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the welcome plugin.";
+ };
+ motd = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Welcome message displayed to clients after connecting
+ and with the !motd command.
+ '';
+ };
+ rules = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Rules message, displayed to clients with the !rules command.
+ '';
+ };
+ };
+
+ history = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the history plugin.";
+ };
+ max = mkOption {
+ type = types.int;
+ default = 200;
+ description = "The maximum number of messages to keep in history";
+ };
+ default = mkOption {
+ type = types.int;
+ default = 10;
+ description = "When !history is provided without arguments, then this default number of messages are returned.";
+ };
+ connect = mkOption {
+ type = types.int;
+ default = 5;
+ description = "The number of chat history messages to send when users connect (0 = do not send any history).";
+ };
+ };
+
+ };
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ users = {
+ extraUsers = singleton {
+ name = "uhub";
+ uid = config.ids.uids.uhub;
+ };
+ extraGroups = singleton {
+ name = "uhub";
+ gid = config.ids.gids.uhub;
+ };
+ };
+
+ systemd.services.uhub = {
+ description = "high performance peer-to-peer hub for the ADC network";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ Type = "notify";
+ ExecStart = "${uhubPkg}/bin/uhub -c ${uhubConfigFile} -u uhub -g uhub -L";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ };
+ };
+ };
+
+}
\ No newline at end of file
diff --git a/nixos/modules/services/misc/zookeeper.nix b/nixos/modules/services/misc/zookeeper.nix
old mode 100755
new mode 100644
diff --git a/nixos/modules/services/monitoring/apcupsd.nix b/nixos/modules/services/monitoring/apcupsd.nix
index 6cc0c122ec6..ffa7be7dd30 100644
--- a/nixos/modules/services/monitoring/apcupsd.nix
+++ b/nixos/modules/services/monitoring/apcupsd.nix
@@ -161,6 +161,7 @@ in
# systemd kills it with SIGKILL.
TimeoutStopSec = 5;
};
+ unitConfig.Documentation = "man:apcupsd(8)";
};
# A special service to tell the UPS to power down/hibernate just before the
diff --git a/nixos/modules/services/monitoring/bosun.nix b/nixos/modules/services/monitoring/bosun.nix
new file mode 100644
index 00000000000..7a53ce17454
--- /dev/null
+++ b/nixos/modules/services/monitoring/bosun.nix
@@ -0,0 +1,136 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.bosun;
+
+ configFile = pkgs.writeText "bosun.conf" ''
+ tsdbHost = ${cfg.opentsdbHost}
+ httpListen = ${cfg.listenAddress}
+ stateFile = ${cfg.stateFile}
+ checkFrequency = 5m
+
+ ${cfg.extraConfig}
+ '';
+
+in {
+
+ options = {
+
+ services.bosun = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to run bosun.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ example = literalExample "pkgs.bosun";
+ description = ''
+ bosun binary to use.
+ '';
+ };
+
+ user = mkOption {
+ type = types.string;
+ default = "bosun";
+ description = ''
+ User account under which bosun runs.
+ '';
+ };
+
+ group = mkOption {
+ type = types.string;
+ default = "bosun";
+ description = ''
+ Group account under which bosun runs.
+ '';
+ };
+
+ opentsdbHost = mkOption {
+ type = types.string;
+ default = "localhost:4242";
+ description = ''
+ Host and port of the OpenTSDB database that stores bosun data.
+ '';
+ };
+
+ listenAddress = mkOption {
+ type = types.string;
+ default = ":8070";
+ description = ''
+ The host address and port that bosun's web interface will listen on.
+ '';
+ };
+
+ stateFile = mkOption {
+ type = types.string;
+ default = "/var/lib/bosun/bosun.state";
+ description = ''
+ Path to bosun's state file.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.string;
+ default = "";
+ description = ''
+ Extra configuration options for Bosun. You should describe your
+ desired templates, alerts, macros, etc through this configuration
+ option.
+
+ A detailed description of the supported syntax can be found at-spi2-atk
+ http://bosun.org/configuration.html
+ '';
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ services.bosun.package = mkDefault pkgs.bosun;
+
+ systemd.services.bosun = {
+ description = "bosun metrics collector (part of Bosun)";
+ wantedBy = [ "multi-user.target" ];
+
+ preStart =
+ ''
+ mkdir -p `dirname ${cfg.stateFile}`;
+ touch ${cfg.stateFile}
+ touch ${cfg.stateFile}.tmp
+
+ if [ "$(id -u)" = 0 ]; then
+ chown ${cfg.user}:${cfg.group} ${cfg.stateFile}
+ chown ${cfg.user}:${cfg.group} ${cfg.stateFile}.tmp
+ fi
+ '';
+
+ serviceConfig = {
+ PermissionsStartOnly = true;
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = ''
+ ${cfg.package}/bin/bosun -c ${configFile}
+ '';
+ };
+ };
+
+ users.extraUsers.bosun = {
+ description = "bosun user";
+ group = "bosun";
+ uid = config.ids.uids.bosun;
+ };
+
+ users.extraGroups.bosun.gid = config.ids.gids.bosun;
+
+ };
+
+}
diff --git a/nixos/modules/services/monitoring/cadvisor.nix b/nixos/modules/services/monitoring/cadvisor.nix
new file mode 100644
index 00000000000..b6cf397f35c
--- /dev/null
+++ b/nixos/modules/services/monitoring/cadvisor.nix
@@ -0,0 +1,98 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.services.cadvisor;
+
+in {
+ options = {
+ services.cadvisor = {
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = "Whether to enable cadvisor service.";
+ };
+
+ host = mkOption {
+ default = "127.0.0.1";
+ type = types.str;
+ description = "Cadvisor listening host";
+ };
+
+ port = mkOption {
+ default = 8080;
+ type = types.int;
+ description = "Cadvisor listening port";
+ };
+
+ storageDriver = mkOption {
+ default = null;
+ type = types.nullOr types.str;
+ example = "influxdb";
+ description = "Cadvisor storage driver.";
+ };
+
+ storageDriverHost = mkOption {
+ default = "localhost:8086";
+ type = types.str;
+ description = "Cadvisor storage driver host.";
+ };
+
+ storageDriverDb = mkOption {
+ default = "root";
+ type = types.str;
+ description = "Cadvisord storage driver database name.";
+ };
+
+ storageDriverUser = mkOption {
+ default = "root";
+ type = types.str;
+ description = "Cadvisor storage driver username.";
+ };
+
+ storageDriverPassword = mkOption {
+ default = "root";
+ type = types.str;
+ description = "Cadvisor storage driver password.";
+ };
+
+ storageDriverSecure = mkOption {
+ default = false;
+ type = types.bool;
+ description = "Cadvisor storage driver, enable secure communication.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.cadvisor = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "docker.service" "influxdb.service" ];
+
+ postStart = mkBefore ''
+ until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.host}:${toString cfg.port}/containers/'; do
+ sleep 1;
+ done
+ '';
+
+ serviceConfig = {
+ ExecStart = ''${pkgs.cadvisor}/bin/cadvisor \
+ -logtostderr=true \
+ -listen_ip=${cfg.host} \
+ -port=${toString cfg.port} \
+ ${optionalString (cfg.storageDriver != null) ''
+ -storage_driver ${cfg.storageDriver} \
+ -storage_driver_user ${cfg.storageDriverHost} \
+ -storage_driver_db ${cfg.storageDriverDb} \
+ -storage_driver_user ${cfg.storageDriverUser} \
+ -storage_driver_password ${cfg.storageDriverPassword} \
+ ${optionalString cfg.storageDriverSecure "-storage_driver_secure"}
+ ''}
+ '';
+ };
+ };
+
+ virtualisation.docker.enable = mkDefault true;
+ };
+}
diff --git a/nixos/modules/services/monitoring/collectd.nix b/nixos/modules/services/monitoring/collectd.nix
new file mode 100644
index 00000000000..717c2c48168
--- /dev/null
+++ b/nixos/modules/services/monitoring/collectd.nix
@@ -0,0 +1,116 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.services.collectd;
+
+ conf = pkgs.writeText "collectd.conf" ''
+ BaseDir "${cfg.dataDir}"
+ PIDFile "${cfg.pidFile}"
+ AutoLoadPlugin ${if cfg.autoLoadPlugin then "true" else "false"}
+ Hostname ${config.networking.hostName}
+
+ LoadPlugin syslog
+
+ LogLevel "info"
+ NotifyLevel "OKAY"
+
+
+ ${concatMapStrings (f: ''
+ Include "${f}"
+ '') cfg.include}
+
+ ${cfg.extraConfig}
+ '';
+
+in {
+ options.services.collectd = with types; {
+ enable = mkOption {
+ default = false;
+ description = ''
+ Whether to enable collectd agent.
+ '';
+ type = bool;
+ };
+
+ user = mkOption {
+ default = "collectd";
+ description = ''
+ User under which to run collectd.
+ '';
+ type = nullOr str;
+ };
+
+ dataDir = mkOption {
+ default = "/var/lib/collectd";
+ description = ''
+ Data directory for collectd agent.
+ '';
+ type = path;
+ };
+
+ pidFile = mkOption {
+ default = "/var/run/collectd.pid";
+ description = ''
+ Location of collectd pid file.
+ '';
+ type = path;
+ };
+
+ autoLoadPlugin = mkOption {
+ default = false;
+ description = ''
+ Enable plugin autoloading.
+ '';
+ type = bool;
+ };
+
+ include = mkOption {
+ default = [];
+ description = ''
+ Additional paths to load config from.
+ '';
+ type = listOf str;
+ };
+
+ extraConfig = mkOption {
+ default = "";
+ description = ''
+ Extra configuration for collectd.
+ '';
+ type = lines;
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.collectd = {
+ description = "Collectd Monitoring Agent";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ ExecStart = "${pkgs.collectd}/sbin/collectd -C ${conf} -P ${cfg.pidFile}";
+ Type = "forking";
+ PIDFile = cfg.pidFile;
+ User = optional (cfg.user!="root") cfg.user;
+ PermissionsStartOnly = true;
+ };
+
+ preStart = ''
+ mkdir -m 0700 -p ${cfg.dataDir}
+ install -D /dev/null ${cfg.pidFile}
+ if [ "$(id -u)" = 0 ]; then
+ chown -R ${cfg.user} ${cfg.dataDir};
+ chown ${cfg.user} ${cfg.pidFile}
+ fi
+ '';
+ };
+
+ users.extraUsers = optional (cfg.user == "collectd") {
+ name = "collectd";
+ uid = config.ids.uids.collectd;
+ };
+ };
+}
diff --git a/nixos/modules/services/monitoring/dd-agent.nix b/nixos/modules/services/monitoring/dd-agent.nix
index deef64d6998..dc51a7c7486 100644
--- a/nixos/modules/services/monitoring/dd-agent.nix
+++ b/nixos/modules/services/monitoring/dd-agent.nix
@@ -140,6 +140,7 @@ in {
Restart = "always";
RestartSec = 2;
};
+ environment.SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
restartTriggers = [ pkgs.dd-agent ddConf postgresqlConfig nginxConfig ];
};
diff --git a/nixos/modules/services/monitoring/graphite.nix b/nixos/modules/services/monitoring/graphite.nix
index dbfe0ee182a..bbbbcbccb9b 100644
--- a/nixos/modules/services/monitoring/graphite.nix
+++ b/nixos/modules/services/monitoring/graphite.nix
@@ -8,6 +8,24 @@ let
dataDir = cfg.dataDir;
+ graphiteApiConfig = pkgs.writeText "graphite-api.yaml" ''
+ time_zone: ${config.time.timeZone}
+ search_index: ${dataDir}/index
+ ${optionalString (cfg.api.finders != []) ''finders:''}
+ ${concatMapStringsSep "\n" (f: " - " + f.moduleName) cfg.api.finders}
+ ${optionalString (cfg.api.functions != []) ''functions:''}
+ ${concatMapStringsSep "\n" (f: " - " + f) cfg.api.functions}
+ ${cfg.api.extraConfig}
+ '';
+
+ seyrenConfig = {
+ SEYREN_URL = cfg.seyren.seyrenUrl;
+ MONGO_URL = cfg.seyren.mongoUrl;
+ GRAPHITE_URL = cfg.seyren.graphiteUrl;
+ } // cfg.seyren.extraConfig;
+
+ pagerConfig = pkgs.writeText "alarms.yaml" cfg.pager.alerts;
+
configDir = pkgs.buildEnv {
name = "graphite-config";
paths = lists.filter (el: el != null) [
@@ -65,6 +83,80 @@ in {
};
};
+ api = {
+ enable = mkOption {
+ description = ''
+ Whether to enable graphite api. Graphite api is lightweight alternative
+ to graphite web, with api and without dashboard. It's advised to use
+ grafana as alternative dashboard and influxdb as alternative to
+ graphite carbon.
+
+ For more information visit
+
+ '';
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ finders = mkOption {
+ description = "List of finder plugins to load.";
+ default = [];
+ example = [ pkgs.python27Packages.graphite_influxdb ];
+ type = types.listOf types.package;
+ };
+
+ functions = mkOption {
+ description = "List of functions to load.";
+ default = [
+ "graphite_api.functions.SeriesFunctions"
+ "graphite_api.functions.PieFunctions"
+ ];
+ type = types.listOf types.str;
+ };
+
+ host = mkOption {
+ description = "Graphite web service listen address.";
+ default = "127.0.0.1";
+ type = types.str;
+ };
+
+ port = mkOption {
+ description = "Graphite api service port.";
+ default = 8080;
+ type = types.int;
+ };
+
+ package = mkOption {
+ description = "Package to use for graphite api.";
+ default = pkgs.python27Packages.graphite_api;
+ type = types.package;
+ };
+
+ extraConfig = mkOption {
+ description = "Extra configuration for graphite api.";
+ default = ''
+ whisper:
+ directories:
+ - ${dataDir}/whisper
+ '';
+ example = literalExample ''
+ allowed_origins:
+ - dashboard.example.com
+ cheat_times: true
+ influxdb:
+ host: localhost
+ port: 8086
+ user: influxdb
+ pass: influxdb
+ db: metrics
+ cache:
+ CACHE_TYPE: 'filesystem'
+ CACHE_DIR: '/tmp/graphite-api-cache'
+ '';
+ type = types.str;
+ };
+ };
+
carbon = {
config = mkOption {
description = "Content of carbon configuration file.";
@@ -172,122 +264,289 @@ in {
'';
};
};
+
+ seyren = {
+ enable = mkOption {
+ description = "Whether to enable seyren service.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ port = mkOption {
+ description = "Seyren listening port.";
+ default = 8081;
+ type = types.int;
+ };
+
+ seyrenUrl = mkOption {
+ default = "http://localhost:${toString cfg.seyren.port}/";
+ description = "Host where seyren is accessible.";
+ type = types.str;
+ };
+
+ graphiteUrl = mkOption {
+ default = "http://${cfg.web.host}:${toString cfg.web.port}";
+ description = "Host where graphite service runs.";
+ type = types.str;
+ };
+
+ mongoUrl = mkOption {
+ default = "mongodb://${config.services.mongodb.bind_ip}:27017/seyren";
+ description = "Mongodb connection string.";
+ type = types.str;
+ };
+
+ extraConfig = mkOption {
+ default = {};
+ description = ''
+ Extra seyren configuration. See
+
+ '';
+ type = types.attrsOf types.str;
+ example = literalExample ''
+ {
+ GRAPHITE_USERNAME = "user";
+ GRAPHITE_PASSWORD = "pass";
+ }
+ '';
+ };
+ };
+
+ pager = {
+ enable = mkOption {
+ description = ''
+ Whether to enable graphite-pager service. For more information visit
+
+ '';
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ redisUrl = mkOption {
+ description = "Redis connection string.";
+ default = "redis://localhost:${toString config.services.redis.port}/";
+ type = types.str;
+ };
+
+ graphiteUrl = mkOption {
+ description = "URL to your graphite service.";
+ default = "http://${cfg.web.host}:${toString cfg.web.port}";
+ type = types.str;
+ };
+
+ alerts = mkOption {
+ description = "Alerts configuration for graphite-pager.";
+ default = ''
+ alerts:
+ - target: constantLine(100)
+ warning: 90
+ critical: 200
+ name: Test
+ '';
+ example = literalExample ''
+ pushbullet_key: pushbullet_api_key
+ alerts:
+ - target: stats.seatgeek.app.deal_quality.venue_info_cache.hit
+ warning: .5
+ critical: 1
+ name: Deal quality venue cache hits
+ '';
+ type = types.lines;
+ };
+ };
};
###### implementation
- config = mkIf (cfg.carbon.enableAggregator || cfg.carbon.enableCache || cfg.carbon.enableRelay || cfg.web.enable) {
- systemd.services.carbonCache = {
- enable = cfg.carbon.enableCache;
- description = "Graphite Data Storage Backend";
- wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
- environment = carbonEnv;
- serviceConfig = {
- ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}";
- User = "graphite";
- Group = "graphite";
- PermissionsStartOnly = true;
- };
- restartTriggers = [
- pkgs.pythonPackages.carbon
- configDir
- ];
- preStart = ''
- mkdir -p ${cfg.dataDir}/whisper
- chmod 0700 ${cfg.dataDir}/whisper
- chown -R graphite:graphite ${cfg.dataDir}
- '';
- };
-
- systemd.services.carbonAggregator = {
- enable = cfg.carbon.enableAggregator;
- description = "Carbon Data Aggregator";
- wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
- environment = carbonEnv;
- serviceConfig = {
- ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}";
- User = "graphite";
- Group = "graphite";
- };
- restartTriggers = [
- pkgs.pythonPackages.carbon
- configDir
- ];
- };
-
- systemd.services.carbonRelay = {
- enable = cfg.carbon.enableRelay;
- description = "Carbon Data Relay";
- wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
- environment = carbonEnv;
- serviceConfig = {
- ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}";
- User = "graphite";
- Group = "graphite";
- };
- restartTriggers = [
- pkgs.pythonPackages.carbon
- configDir
- ];
- };
-
- systemd.services.graphiteWeb = {
- enable = cfg.web.enable;
- description = "Graphite Web Interface";
- wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
- path = [ pkgs.perl ];
- environment = {
- PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages";
- DJANGO_SETTINGS_MODULE = "graphite.settings";
- GRAPHITE_CONF_DIR = "/etc/graphite/";
- GRAPHITE_STORAGE_DIR = dataDir;
- };
- serviceConfig = {
- ExecStart = ''
- ${pkgs.python27Packages.waitress}/bin/waitress-serve \
- --host=${cfg.web.host} --port=${toString cfg.web.port} \
- --call django.core.handlers.wsgi:WSGIHandler'';
- User = "graphite";
- Group = "graphite";
- PermissionsStartOnly = true;
- };
- preStart = ''
- if ! test -e ${dataDir}/db-created; then
- mkdir -p ${dataDir}/{whisper/,log/webapp/}
- chmod 0700 ${dataDir}/{whisper/,log/webapp/}
-
- # populate database
- ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput
-
- # create index
- ${pkgs.python27Packages.graphite_web}/bin/build-index.sh
-
- touch ${dataDir}/db-created
-
+ config = mkMerge [
+ (mkIf cfg.carbon.enableCache {
+ systemd.services.carbonCache = {
+ description = "Graphite Data Storage Backend";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment = carbonEnv;
+ serviceConfig = {
+ ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}";
+ User = "graphite";
+ Group = "graphite";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ mkdir -p ${cfg.dataDir}/whisper
+ chmod 0700 ${cfg.dataDir}/whisper
chown -R graphite:graphite ${cfg.dataDir}
- fi
- '';
- restartTriggers = [
- pkgs.python27Packages.graphite_web
+ '';
+ };
+ })
+
+ (mkIf cfg.carbon.enableAggregator {
+ systemd.services.carbonAggregator = {
+ enable = cfg.carbon.enableAggregator;
+ description = "Carbon Data Aggregator";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment = carbonEnv;
+ serviceConfig = {
+ ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}";
+ User = "graphite";
+ Group = "graphite";
+ };
+ };
+ })
+
+ (mkIf cfg.carbon.enableRelay {
+ systemd.services.carbonRelay = {
+ description = "Carbon Data Relay";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment = carbonEnv;
+ serviceConfig = {
+ ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}";
+ User = "graphite";
+ Group = "graphite";
+ };
+ };
+ })
+
+ (mkIf (cfg.carbon.enableCache || cfg.carbon.enableAggregator || cfg.carbon.enableRelay) {
+ environment.systemPackages = [
+ pkgs.pythonPackages.carbon
];
- };
+ })
- environment.systemPackages = [
- pkgs.pythonPackages.carbon
- pkgs.python27Packages.graphite_web
- pkgs.python27Packages.waitress
- ];
+ (mkIf cfg.web.enable {
+ systemd.services.graphiteWeb = {
+ description = "Graphite Web Interface";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ path = [ pkgs.perl ];
+ environment = {
+ PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages";
+ DJANGO_SETTINGS_MODULE = "graphite.settings";
+ GRAPHITE_CONF_DIR = configDir;
+ GRAPHITE_STORAGE_DIR = dataDir;
+ };
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.python27Packages.waitress}/bin/waitress-serve \
+ --host=${cfg.web.host} --port=${toString cfg.web.port} \
+ --call django.core.handlers.wsgi:WSGIHandler'';
+ User = "graphite";
+ Group = "graphite";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ if ! test -e ${dataDir}/db-created; then
+ mkdir -p ${dataDir}/{whisper/,log/webapp/}
+ chmod 0700 ${dataDir}/{whisper/,log/webapp/}
- users.extraUsers = singleton {
- name = "graphite";
- uid = config.ids.uids.graphite;
- description = "Graphite daemon user";
- home = dataDir;
- };
- users.extraGroups.graphite.gid = config.ids.gids.graphite;
- };
+ # populate database
+ ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput
+
+ # create index
+ ${pkgs.python27Packages.graphite_web}/bin/build-index.sh
+
+ touch ${dataDir}/db-created
+
+ chown -R graphite:graphite ${cfg.dataDir}
+ fi
+ '';
+ };
+
+ environment.systemPackages = [ pkgs.python27Packages.graphite_web ];
+ })
+
+ (mkIf cfg.api.enable {
+ systemd.services.graphiteApi = {
+ description = "Graphite Api Interface";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment = {
+ PYTHONPATH =
+ "${cfg.api.package}/lib/python2.7/site-packages:" +
+ concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders;
+ GRAPHITE_API_CONFIG = graphiteApiConfig;
+ LD_LIBRARY_PATH = "${pkgs.cairo}/lib";
+ };
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.python27Packages.waitress}/bin/waitress-serve \
+ --host=${cfg.api.host} --port=${toString cfg.api.port} \
+ graphite_api.app:app
+ '';
+ User = "graphite";
+ Group = "graphite";
+ PermissionsStartOnly = true;
+ };
+ preStart = ''
+ if ! test -e ${dataDir}/db-created; then
+ mkdir -p ${dataDir}/cache/
+ chmod 0700 ${dataDir}/cache/
+
+ touch ${dataDir}/db-created
+
+ chown -R graphite:graphite ${cfg.dataDir}
+ fi
+ '';
+ };
+ })
+
+ (mkIf cfg.seyren.enable {
+ systemd.services.seyren = {
+ description = "Graphite Alerting Dashboard";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "mongodb.service" ];
+ environment = seyrenConfig;
+ serviceConfig = {
+ ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}";
+ WorkingDirectory = dataDir;
+ User = "graphite";
+ Group = "graphite";
+ };
+ preStart = ''
+ if ! test -e ${dataDir}/db-created; then
+ mkdir -p ${dataDir}
+ chown -R graphite:graphite ${dataDir}
+ fi
+ '';
+ };
+
+ services.mongodb.enable = mkDefault true;
+ })
+
+ (mkIf cfg.pager.enable {
+ systemd.services.graphitePager = {
+ description = "Graphite Pager Alerting Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "redis.service" ];
+ environment = {
+ REDIS_URL = cfg.pager.redisUrl;
+ GRAPHITE_URL = cfg.pager.graphiteUrl;
+ };
+ serviceConfig = {
+ ExecStart = "${pkgs.pythonPackages.graphite_pager}/bin/graphite-pager --config ${pagerConfig}";
+ User = "graphite";
+ Group = "graphite";
+ };
+ };
+
+ services.redis.enable = mkDefault true;
+
+ environment.systemPackages = [ pkgs.pythonPackages.graphite_pager ];
+ })
+
+ (mkIf (
+ cfg.carbon.enableCache || cfg.carbon.enableAggregator || cfg.carbon.enableRelay ||
+ cfg.web.enable || cfg.api.enable ||
+ cfg.seyren.enable || cfg.pager.enable
+ ) {
+ users.extraUsers = singleton {
+ name = "graphite";
+ uid = config.ids.uids.graphite;
+ description = "Graphite daemon user";
+ home = dataDir;
+ };
+ users.extraGroups.graphite.gid = config.ids.gids.graphite;
+ })
+ ];
}
diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix
index 21840bc67e8..31afa859e25 100644
--- a/nixos/modules/services/monitoring/munin.nix
+++ b/nixos/modules/services/monitoring/munin.nix
@@ -34,10 +34,10 @@ let
cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file)
wrapProgram $file \
- --set PATH "/run/current-system/sw/bin:/run/current-system/sw/sbin" \
+ --set PATH "/var/setuid-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \
--set MUNIN_LIBDIR "${pkgs.munin}/lib" \
--set MUNIN_PLUGSTATE "/var/run/munin"
-
+
# munin uses markers to tell munin-node-configure what a plugin can do
echo "#%# family=$family" >> $file
echo "#%# capabilities=$cap" >> $file
@@ -57,7 +57,7 @@ let
rundir /var/run/munin
${cronCfg.extraGlobalConfig}
-
+
${cronCfg.hosts}
'';
@@ -72,10 +72,10 @@ let
group root
host_name ${config.networking.hostName}
setsid 0
-
+
# wrapped plugins by makeWrapper being with dots
ignore_file ^\.
-
+
allow ^127\.0\.0\.1$
${nodeCfg.extraConfig}
@@ -97,7 +97,7 @@ in
See .
'';
};
-
+
extraConfig = mkOption {
default = "";
description = ''
@@ -118,7 +118,7 @@ in
Enable munin-cron. Takes care of all heavy lifting to collect data from
nodes and draws graphs to html. Runs munin-update, munin-limits,
munin-graphs and munin-html in that order.
-
+
HTML output is in /var/www/munin/ , configure your
favourite webserver to serve static files.
'';
@@ -138,7 +138,7 @@ in
};
'';
};
-
+
extraGlobalConfig = mkOption {
default = "";
description = ''
@@ -160,7 +160,7 @@ in
'';
};
-
+
};
};
@@ -194,7 +194,7 @@ in
mkdir -p /etc/munin/plugins
rm -rf /etc/munin/plugins/*
- PATH="/run/current-system/sw/bin:/run/current-system/sw/sbin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash
+ PATH="/var/setuid-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash
'';
serviceConfig = {
ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/";
diff --git a/nixos/modules/services/monitoring/riemann-dash.nix b/nixos/modules/services/monitoring/riemann-dash.nix
index 148dc046805..523f74cb72b 100644
--- a/nixos/modules/services/monitoring/riemann-dash.nix
+++ b/nixos/modules/services/monitoring/riemann-dash.nix
@@ -15,7 +15,7 @@ let
launcher = writeScriptBin "riemann-dash" ''
#!/bin/sh
- exec ${rubyLibs.riemann_dash}/bin/riemann-dash ${conf}
+ exec ${pkgs.riemann-dash}/bin/riemann-dash ${conf}
'';
in {
diff --git a/nixos/modules/services/monitoring/riemann.nix b/nixos/modules/services/monitoring/riemann.nix
index a1935c29a04..ac5d0134a80 100644
--- a/nixos/modules/services/monitoring/riemann.nix
+++ b/nixos/modules/services/monitoring/riemann.nix
@@ -11,11 +11,15 @@ let
cfg.extraClasspathEntries ++ [ "${riemann}/share/java/riemann.jar" ]
);
+ riemannConfig = concatStringsSep "\n" (
+ [cfg.config] ++ (map (f: ''(load-file "${f}")'') cfg.configFiles)
+ );
+
launcher = writeScriptBin "riemann" ''
#!/bin/sh
- exec ${openjdk}/bin/java ${concatStringsSep "\n" cfg.extraJavaOpts} \
+ exec ${jdk}/bin/java ${concatStringsSep "\n" cfg.extraJavaOpts} \
-cp ${classpath} \
- riemann.bin ${writeText "riemann.config" cfg.config}
+ riemann.bin ${writeText "riemann-config.clj" riemannConfig}
'';
in {
@@ -36,6 +40,16 @@ in {
Contents of the Riemann configuration file.
'';
};
+ configFiles = mkOption {
+ type = with types; listOf path;
+ default = [];
+ description = ''
+ Extra files containing Riemann configuration. These files will be
+ loaded at runtime by Riemann (with Clojure's
+ load-file function) at the end of the
+ configuration.
+ '';
+ };
extraClasspathEntries = mkOption {
type = with types; listOf str;
default = [];
diff --git a/nixos/modules/services/monitoring/scollector.nix b/nixos/modules/services/monitoring/scollector.nix
new file mode 100644
index 00000000000..0143d2e327b
--- /dev/null
+++ b/nixos/modules/services/monitoring/scollector.nix
@@ -0,0 +1,125 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.scollector;
+
+ collectors = pkgs.runCommand "collectors" {}
+ ''
+ mkdir -p $out
+ ${lib.concatStringsSep
+ "\n"
+ (lib.mapAttrsToList
+ (frequency: binaries:
+ "mkdir -p $out/${frequency}\n" +
+ (lib.concatStringsSep
+ "\n"
+ (map (path: "ln -s ${path} $out/${frequency}/$(basename ${path})")
+ binaries)))
+ cfg.collectors)}
+ '';
+
+ cmdLineOpts = concatStringsSep " " (
+ [ "-h=${cfg.bosunHost}" "-c=${collectors}" ] ++ cfg.extraOpts
+ );
+
+in {
+
+ options = {
+
+ services.scollector = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to run scollector.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.scollector;
+ example = literalExample "pkgs.scollector";
+ description = ''
+ scollector binary to use.
+ '';
+ };
+
+ user = mkOption {
+ type = types.string;
+ default = "scollector";
+ description = ''
+ User account under which scollector runs.
+ '';
+ };
+
+ group = mkOption {
+ type = types.string;
+ default = "scollector";
+ description = ''
+ Group account under which scollector runs.
+ '';
+ };
+
+ bosunHost = mkOption {
+ type = types.string;
+ default = "localhost:8070";
+ description = ''
+ Host and port of the bosun server that will store the collected
+ data.
+ '';
+ };
+
+ collectors = mkOption {
+ type = types.attrs;
+ default = {};
+ example = literalExample "{ 0 = [ \"\${postgresStats}/bin/collect-stats\" ]; }";
+ description = ''
+ An attribute set mapping the frequency of collection to a list of
+ binaries that should be executed at that frequency. You can use "0"
+ to run a binary forever.
+ '';
+ };
+
+ extraOpts = mkOption {
+ type = with types; listOf str;
+ default = [];
+ example = [ "-d" ];
+ description = ''
+ Extra scollector command line options
+ '';
+ };
+
+ };
+
+ };
+
+ config = mkIf config.services.scollector.enable {
+
+ systemd.services.scollector = {
+ description = "scollector metrics collector (part of Bosun)";
+ wantedBy = [ "multi-user.target" ];
+
+ path = [ pkgs.coreutils pkgs.iproute ];
+
+ serviceConfig = {
+ PermissionsStartOnly = true;
+ User = cfg.user;
+ Group = cfg.group;
+ ExecStart = "${cfg.package}/bin/scollector ${cmdLineOpts}";
+ };
+ };
+
+ users.extraUsers.scollector = {
+ description = "scollector user";
+ group = "scollector";
+ uid = config.ids.uids.scollector;
+ };
+
+ users.extraGroups.scollector.gid = config.ids.gids.scollector;
+
+ };
+
+}
diff --git a/nixos/modules/services/monitoring/statsd.nix b/nixos/modules/services/monitoring/statsd.nix
index 74f3deb4c29..7d7ca27bb2f 100644
--- a/nixos/modules/services/monitoring/statsd.nix
+++ b/nixos/modules/services/monitoring/statsd.nix
@@ -8,13 +8,20 @@ let
configFile = pkgs.writeText "statsd.conf" ''
{
- host: "${cfg.host}",
+ address: "${cfg.host}",
port: "${toString cfg.port}",
mgmt_address: "${cfg.mgmt_address}",
mgmt_port: "${toString cfg.mgmt_port}",
- backends: [${concatMapStrings (el: ''"./backends/${el}",'') cfg.backends}],
- graphiteHost: "${cfg.graphiteHost}",
- graphitePort: "${toString cfg.graphitePort}",
+ backends: [${concatMapStringsSep "," (el: if (nixType el) == "string" then ''"./backends/${el}"'' else ''"${head el.names}"'') cfg.backends}],
+ ${optionalString (cfg.graphiteHost!=null) ''graphiteHost: "${cfg.graphiteHost}",''}
+ ${optionalString (cfg.graphitePort!=null) ''graphitePort: "${toString cfg.graphitePort}",''}
+ console: {
+ prettyprint: false
+ },
+ log: {
+ backend: "syslog"
+ },
+ automaticConfigReload: false${optionalString (cfg.extraConfig != null) ","}
${cfg.extraConfig}
}
'';
@@ -46,7 +53,7 @@ in
};
mgmt_address = mkOption {
- description = "Address to run managment TCP interface on";
+ description = "Address to run management TCP interface on";
default = "127.0.0.1";
type = types.str;
};
@@ -58,26 +65,28 @@ in
};
backends = mkOption {
- description = "List of backends statsd will use for data persistance";
+ description = "List of backends statsd will use for data persistence";
default = ["graphite"];
+ example = ["graphite" pkgs.nodePackages."statsd-influxdb-backend"];
+ type = types.listOf (types.either types.str types.package);
};
graphiteHost = mkOption {
description = "Hostname or IP of Graphite server";
- default = config.services.graphite.web.host;
- type = types.str;
+ default = null;
+ type = types.nullOr types.str;
};
graphitePort = mkOption {
description = "Port of Graphite server (i.e. carbon-cache).";
- default = 2003;
- type = types.uniq types.int;
+ default = null;
+ type = types.nullOr types.int;
};
extraConfig = mkOption {
- default = "";
description = "Extra configuration options for statsd";
- type = types.str;
+ default = "";
+ type = types.nullOr types.str;
};
};
@@ -95,6 +104,9 @@ in
systemd.services.statsd = {
description = "Statsd Server";
wantedBy = [ "multi-user.target" ];
+ environment = {
+ NODE_PATH=concatMapStringsSep ":" (el: "${el}/lib/node_modules") (filter (el: (nixType el) != "string") cfg.backends);
+ };
serviceConfig = {
ExecStart = "${pkgs.nodePackages.statsd}/bin/statsd ${configFile}";
User = "statsd";
diff --git a/nixos/modules/services/monitoring/teamviewer.nix b/nixos/modules/services/monitoring/teamviewer.nix
new file mode 100644
index 00000000000..beba5dcd1b0
--- /dev/null
+++ b/nixos/modules/services/monitoring/teamviewer.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.teamviewer;
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.teamviewer.enable = mkEnableOption "teamviewer daemon";
+
+ };
+
+ ###### implementation
+
+ config = mkIf (cfg.enable) {
+
+ environment.systemPackages = [ pkgs.teamviewer ];
+
+ systemd.services.teamviewerd = {
+ description = "TeamViewer remote control daemon";
+
+ wantedBy = [ "graphical.target" ];
+ after = [ "NetworkManager-wait-online.service" "network.target" ];
+
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${pkgs.teamviewer}/bin/teamviewerd -d";
+ PIDFile = "/run/teamviewerd.pid";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ Restart = "on-abort";
+ StartLimitInterval = "60";
+ StartLimitBurst = "10";
+ };
+ };
+ };
+
+}
diff --git a/nixos/modules/services/monitoring/zabbix-server.nix b/nixos/modules/services/monitoring/zabbix-server.nix
index ca283ea2a99..acd1279ddf4 100644
--- a/nixos/modules/services/monitoring/zabbix-server.nix
+++ b/nixos/modules/services/monitoring/zabbix-server.nix
@@ -32,6 +32,8 @@ let
${optionalString (cfg.dbPassword != "") ''
DBPassword = ${cfg.dbPassword}
''}
+
+ ${config.services.zabbixServer.extraConfig}
'';
useLocalPostgres = cfg.dbServer == "localhost" || cfg.dbServer == "";
@@ -46,6 +48,7 @@ in
services.zabbixServer.enable = mkOption {
default = false;
+ type = types.bool;
description = ''
Whether to run the Zabbix server on this machine.
'';
@@ -53,6 +56,7 @@ in
services.zabbixServer.dbServer = mkOption {
default = "localhost";
+ type = types.str;
description = ''
Hostname or IP address of the database server.
Use an empty string ("") to use peer authentication.
@@ -61,9 +65,18 @@ in
services.zabbixServer.dbPassword = mkOption {
default = "";
+ type = types.str;
description = "Password used to connect to the database server.";
};
+ services.zabbixServer.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Configuration that is injected verbatim into the configuration file.
+ '';
+ };
+
};
###### implementation
diff --git a/nixos/modules/services/network-filesystems/diod.nix b/nixos/modules/services/network-filesystems/diod.nix
new file mode 100644
index 00000000000..7de7acaa4a0
--- /dev/null
+++ b/nixos/modules/services/network-filesystems/diod.nix
@@ -0,0 +1,160 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+ cfg = config.services.diod;
+
+ diodBool = b: if b then "1" else "0";
+
+ diodConfig = pkgs.writeText "diod.conf" ''
+ allsquash = ${diodBool cfg.allsquash}
+ auth_required = ${diodBool cfg.authRequired}
+ exportall = ${diodBool cfg.exportall}
+ exportopts = "${concatStringsSep "," cfg.exportopts}"
+ exports = { ${concatStringsSep ", " (map (s: ''"${s}"'' ) cfg.exports)} }
+ listen = { ${concatStringsSep ", " (map (s: ''"${s}"'' ) cfg.listen)} }
+ logdest = "${cfg.logdest}"
+ nwthreads = ${toString cfg.nwthreads}
+ squashuser = "${cfg.squashuser}"
+ statfs_passthru = ${diodBool cfg.statfsPassthru}
+ userdb = ${diodBool cfg.userdb}
+ ${cfg.extraConfig}
+ '';
+in
+{
+ options = {
+ services.diod = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to enable the diod 9P file server.";
+ };
+
+ listen = mkOption {
+ type = types.listOf types.str;
+ default = [ "0.0.0.0:564" ];
+ description = ''
+ [ "IP:PORT" [,"IP:PORT",...] ]
+ List the interfaces and ports that diod should listen on.
+ '';
+ };
+
+ exports = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ List the file systems that clients will be allowed to mount. All paths should
+ be fully qualified. The exports table can include two types of element:
+ a string element (as above),
+ or an alternate table element form { path="/path", opts="ro" }.
+ In the alternate form, the (optional) opts attribute is a comma-separated list
+ of export options. The two table element forms can be mixed in the exports
+ table. Note that although diod will not traverse file system boundaries for a
+ given mount due to inode uniqueness constraints, subdirectories of a file
+ system can be separately exported.
+ '';
+ };
+
+ exportall = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Export all file systems listed in /proc/mounts. If new file systems are mounted
+ after diod has started, they will become immediately mountable. If there is a
+ duplicate entry for a file system in the exports list, any options listed in
+ the exports entry will apply.
+ '';
+ };
+
+ exportopts = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ Establish a default set of export options. These are overridden, not appended
+ to, by opts attributes in an "exports" entry.
+ '';
+ };
+
+ nwthreads = mkOption {
+ type = types.int;
+ default = 16;
+ description = ''
+ Sets the (fixed) number of worker threads created to handle 9P
+ requests for a unique aname.
+ '';
+ };
+
+ authRequired = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Allow clients to connect without authentication, i.e. without a valid MUNGE credential.
+ '';
+ };
+
+ userdb = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ This option disables password/group lookups. It allows any uid to attach and
+ assumes gid=uid, and supplementary groups contain only the primary gid.
+ '';
+ };
+
+ allsquash = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Remap all users to "nobody". The attaching user need not be present in the
+ password file.
+ '';
+ };
+
+ squashuser = mkOption {
+ type = types.str;
+ default = "nobody";
+ description = ''
+ Change the squash user. The squash user must be present in the password file.
+ '';
+ };
+
+ logdest = mkOption {
+ type = types.str;
+ default = "syslog:daemon:err";
+ description = ''
+ Set the destination for logging.
+ The value has the form of "syslog:facility:level" or "filename".
+ '';
+ };
+
+
+ statfsPassthru = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ This option configures statfs to return the host file system's type
+ rather than V9FS_MAGIC.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Extra configuration options for diod.conf.";
+ };
+ };
+ };
+
+ config = mkIf config.services.diod.enable {
+ environment.systemPackages = [ pkgs.diod ];
+
+ systemd.services.diod = {
+ description = "diod 9P file server";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.diod}/sbin/diod -f -c ${diodConfig}";
+ Capabilities = "cap_net_bind_service+=ep";
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/network-filesystems/drbd.nix b/nixos/modules/services/network-filesystems/drbd.nix
index b914724abfe..1bd67206444 100644
--- a/nixos/modules/services/network-filesystems/drbd.nix
+++ b/nixos/modules/services/network-filesystems/drbd.nix
@@ -44,7 +44,7 @@ let cfg = config.services.drbd; in
boot.extraModprobeConfig =
''
- options drbd usermode_helper=/run/current-system/sw/sbin/drbdadm
+ options drbd usermode_helper=/run/current-system/sw/bin/drbdadm
'';
environment.etc = singleton
diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix
index 2217fec3b0f..33b7ec3d9f1 100644
--- a/nixos/modules/services/network-filesystems/nfsd.nix
+++ b/nixos/modules/services/network-filesystems/nfsd.nix
@@ -56,6 +56,21 @@ in
default = false;
description = "Whether to create the mount points in the exports file at startup time.";
};
+
+ mountdPort = mkOption {
+ default = null;
+ example = 4002;
+ description = ''
+ Use fixed port for rpc.mountd, useful if server is behind firewall.
+ '';
+ };
+
+ lockdPort = mkOption {
+ default = 0;
+ description = ''
+ Fix the lockd port number. This can help setting firewall rules for NFS.
+ '';
+ };
};
};
@@ -71,7 +86,7 @@ in
boot.supportedFilesystems = [ "nfs" ]; # needed for statd and idmapd
- environment.systemPackages = [ pkgs.nfsUtils ];
+ environment.systemPackages = [ pkgs.nfs-utils ];
environment.etc = singleton
{ source = exports;
@@ -89,13 +104,16 @@ in
after = [ "rpcbind.service" "mountd.service" "idmapd.service" ];
before = [ "statd.service" ];
- path = [ pkgs.nfsUtils ];
+ path = [ pkgs.nfs-utils ];
script =
''
# Create a state directory required by NFSv4.
mkdir -p /var/lib/nfs/v4recovery
+ ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_tcpport=${builtins.toString cfg.lockdPort}
+ ${pkgs.procps}/sbin/sysctl -w fs.nfs.nlm_udpport=${builtins.toString cfg.lockdPort}
+
rpc.nfsd \
${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} \
${builtins.toString cfg.nproc}
@@ -113,7 +131,7 @@ in
requires = [ "rpcbind.service" ];
after = [ "rpcbind.service" ];
- path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ];
+ path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ];
preStart =
''
@@ -138,7 +156,10 @@ in
restartTriggers = [ exports ];
serviceConfig.Type = "forking";
- serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.mountd rpc.mountd";
+ serviceConfig.ExecStart = ''
+ @${pkgs.nfs-utils}/sbin/rpc.mountd rpc.mountd \
+ ${if cfg.mountdPort != null then "-p ${toString cfg.mountdPort}" else ""}
+ '';
serviceConfig.Restart = "always";
};
diff --git a/nixos/modules/services/network-filesystems/rsyncd.nix b/nixos/modules/services/network-filesystems/rsyncd.nix
index 19aa7efd2ff..2018bfa14a5 100644
--- a/nixos/modules/services/network-filesystems/rsyncd.nix
+++ b/nixos/modules/services/network-filesystems/rsyncd.nix
@@ -6,113 +6,84 @@ let
cfg = config.services.rsyncd;
- motdFile = pkgs.writeText "rsyncd-motd" cfg.motd;
+ motdFile = builtins.toFile "rsyncd-motd" cfg.motd;
- rsyncdCfg = ""
- + optionalString (cfg.motd != "") "motd file = ${motdFile}\n"
- + optionalString (cfg.address != "") "address = ${cfg.address}\n"
- + optionalString (cfg.port != 873) "port = ${toString cfg.port}\n"
- + cfg.extraConfig
- + "\n"
- + flip concatMapStrings cfg.modules (m: "[${m.name}]\n\tpath = ${m.path}\n"
- + optionalString (m.comment != "") "\tcomment = ${m.comment}\n"
- + m.extraConfig
- + "\n"
- );
-
- rsyncdCfgFile = pkgs.writeText "rsyncd.conf" rsyncdCfg;
+ moduleConfig = name:
+ let module = getAttr name cfg.modules; in
+ "[${name}]\n " + (toString (
+ map
+ (key: "${key} = ${toString (getAttr key module)}\n")
+ (attrNames module)
+ ));
+ cfgFile = builtins.toFile "rsyncd.conf"
+ ''
+ ${optionalString (cfg.motd != "") "motd file = ${motdFile}"}
+ ${optionalString (cfg.address != "") "address = ${cfg.address}"}
+ ${optionalString (cfg.port != 873) "port = ${toString cfg.port}"}
+ ${cfg.extraConfig}
+ ${toString (map moduleConfig (attrNames cfg.modules))}
+ '';
in
{
options = {
-
services.rsyncd = {
enable = mkOption {
default = false;
- description = "Whether to enable the rsync daemon.";
+ description = "Whether to enable the rsync daemon.";
};
motd = mkOption {
type = types.string;
default = "";
- description = ''
- Message of the day to display to clients on each connect.
- This usually contains site information and any legal notices.
- '';
+ description = ''
+ Message of the day to display to clients on each connect.
+ This usually contains site information and any legal notices.
+ '';
};
port = mkOption {
default = 873;
- type = types.int;
- description = "TCP port the daemon will listen on.";
+ type = types.int;
+ description = "TCP port the daemon will listen on.";
};
address = mkOption {
default = "";
- example = "192.168.1.2";
- description = ''
- IP address the daemon will listen on; rsyncd will listen on
- all addresses if this is not specified.
- '';
+ example = "192.168.1.2";
+ description = ''
+ IP address the daemon will listen on; rsyncd will listen on
+ all addresses if this is not specified.
+ '';
};
extraConfig = mkOption {
type = types.lines;
- default = "";
- description = ''
- Lines of configuration to add to rsyncd globally.
- See man rsyncd.conf for more options.
- '';
+ default = "";
+ description = ''
+ Lines of configuration to add to rsyncd globally.
+ See man rsyncd.conf for options.
+ '';
};
modules = mkOption {
- default = [ ];
- example = [
- { name = "ftp";
- path = "/home/ftp";
- comment = "ftp export area";
- extraConfig = ''
- secrets file = /etc/rsyncd.secrets
- '';
- }
- ];
- description = "The list of file paths to export.";
- type = types.listOf types.optionSet;
-
- options = {
-
- name = mkOption {
- example = "ftp";
- type = types.string;
- description = "Name of export module.";
- };
-
- comment = mkOption {
- default = "";
- description = ''
- Description string that is displayed next to the module name
- when clients obtain a list of available modules.
- '';
- };
-
- path = mkOption {
- example = "/home/ftp";
- type = types.string;
- description = "Directory to make available in this module.";
- };
-
- extraConfig = mkOption {
- type = types.lines;
- default = "";
- description = ''
- Lines of configuration to add to this module.
- See man rsyncd.conf for more options.
- '';
+ default = {};
+ description = ''
+ A set describing exported directories.
+ See man rsyncd.conf for options.
+ '';
+ type = types.attrsOf (types.attrsOf types.str);
+ example =
+ { srv =
+ { path = "/srv";
+ "read only" = "yes";
+ comment = "Public rsync share.";
+ };
};
- };
};
+
};
};
@@ -120,20 +91,16 @@ in
config = mkIf cfg.enable {
- environment.etc = singleton
- { source = rsyncdCfgFile;
+ environment.etc = singleton {
+ source = cfgFile;
target = "rsyncd.conf";
};
systemd.services.rsyncd = {
description = "Rsync daemon";
wantedBy = [ "multi-user.target" ];
-
- path = [ pkgs.rsync ];
-
serviceConfig.ExecStart = "${pkgs.rsync}/bin/rsync --daemon --no-detach";
};
- networking.firewall.allowedTCPPorts = [ cfg.port ];
};
}
diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index 4218b965cd9..d6babb8e9a5 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -6,52 +6,34 @@ let
cfg = config.services.samba;
- user = "smbguest";
- group = "smbguest";
-
- logDir = "/var/log/samba";
- privateDir = "/var/samba/private";
-
- inherit (pkgs) samba;
+ samba = cfg.package;
setupScript =
''
- if ! test -d /home/smbd ; then
- mkdir -p /home/smbd
- chown ${user} /home/smbd
- chmod a+rwx /home/smbd
- fi
-
- if ! test -d /var/samba ; then
- mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd
- fi
-
- passwdFile="$(${pkgs.gnused}/bin/sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})"
- if [ -n "$passwdFile" ]; then
- echo 'INFO: [samba] creating directory containing passwd file'
- mkdir -p "$(dirname "$passwdFile")"
- fi
-
- mkdir -p ${logDir}
- mkdir -p ${privateDir}
+ mkdir -p /var/lock/samba /var/log/samba /var/cache/samba /var/lib/samba/private
'';
+ shareConfig = name:
+ let share = getAttr name cfg.shares; in
+ "[${name}]\n " + (toString (
+ map
+ (key: "${key} = ${toString (getAttr key share)}\n")
+ (attrNames share)
+ ));
+
configFile = pkgs.writeText "smb.conf"
+ (if cfg.configText != null then cfg.configText else
''
[ global ]
- log file = ${logDir}/log.%m
- private dir = ${privateDir}
- ${optionalString cfg.syncPasswordsByPam "pam password change = true"}
-
- ${if cfg.defaultShare.enable then ''
- [default]
- path = /home/smbd
- read only = ${if cfg.defaultShare.writeable then "no" else "yes"}
- guest ok = ${if cfg.defaultShare.guest then "yes" else "no"}
- ''else ""}
+ security = ${cfg.securityType}
+ passwd program = /var/setuid-wrappers/passwd %u
+ pam password change = ${if cfg.syncPasswordsByPam then "yes" else "no"}
+ invalid users = ${toString cfg.invalidUsers}
${cfg.extraConfig}
- '';
+
+ ${toString (map shareConfig (attrNames cfg.shares))}
+ '');
# This may include nss_ldap, needed for samba if it has to use ldap.
nssModulesPath = config.system.nssModules.path;
@@ -88,86 +70,65 @@ in
services.samba = {
enable = mkOption {
+ type = types.bool;
default = false;
- description = "
+ description = ''
Whether to enable Samba, which provides file and print
services to Windows clients through the SMB/CIFS protocol.
- ";
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.samba;
+ example = pkgs.samba4;
+ description = ''
+ Defines which package should be used for the samba server.
+ '';
};
syncPasswordsByPam = mkOption {
+ type = types.bool;
default = false;
- description = "
- enabling this will add a line directly after pam_unix.so.
+ description = ''
+ Enabling this will add a line directly after pam_unix.so.
Whenever a password is changed the samba password will be updated as well.
However you still yave to add the samba password once using smbpasswd -a user
If you don't want to maintain an extra pwd database you still can send plain text
passwords which is not secure.
- ";
+ '';
+ };
+
+ invalidUsers = mkOption {
+ type = types.listOf types.str;
+ default = [ "root" ];
+ description = ''
+ List of users who are denied to login via Samba.
+ '';
};
extraConfig = mkOption {
- # !!! Bad default.
- default = ''
- # [global] continuing global section here, section is started by nix to set pids etc
-
- smb passwd file = /etc/samba/passwd
-
- # is this useful ?
- domain master = auto
-
- encrypt passwords = Yes
- client plaintext auth = No
-
- # yes: if you use this you probably also want to enable syncPasswordsByPam
- # no: You can still use the pam password database. However
- # passwords will be sent plain text on network (discouraged)
-
- workgroup = Users
- server string = %h
- comment = Samba
- log file = /var/log/samba/log.%m
- log level = 10
- max log size = 50000
- security = ${cfg.securityType}
-
- client lanman auth = Yes
- dns proxy = no
- invalid users = root
- passdb backend = tdbsam
- passwd program = /usr/bin/passwd %u
+ type = types.lines;
+ default = "";
+ description = ''
+ Additional global section and extra section lines go in here.
'';
-
- description = "
- additional global section and extra section lines go in here.
- ";
};
- configFile = mkOption {
- description = "
- internal use to pass filepath to samba pam module
- ";
- };
-
- defaultShare = {
- enable = mkOption {
- description = "Whether to share /home/smbd as 'default'.";
- default = false;
- };
- writeable = mkOption {
- description = "Whether to allow write access to default share.";
- default = false;
- };
- guest = mkOption {
- description = "Whether to allow guest access to default share.";
- default = true;
- };
+ configText = mkOption {
+ type = types.nullOr types.lines;
+ default = null;
+ description = ''
+ Verbatim contents of smb.conf. If null (default), use the
+ autogenerated file from NixOS instead.
+ '';
};
securityType = mkOption {
- description = "Samba security type";
+ type = types.str;
default = "user";
example = "share";
+ description = "Samba security type";
};
nsswins = mkOption {
@@ -180,6 +141,22 @@ in
'';
};
+ shares = mkOption {
+ default = {};
+ description = ''
+ A set describing shared resources.
+ See man smb.conf for options.
+ '';
+ type = types.attrsOf (types.attrsOf types.unspecified);
+ example =
+ { srv =
+ { path = "/srv";
+ "read only" = "yes";
+ comment = "Public samba share.";
+ };
+ };
+ };
+
};
};
@@ -199,14 +176,6 @@ in
(mkIf config.services.samba.enable {
- users.extraUsers.smbguest = {
- description = "Samba service user";
- group = group;
- uid = config.ids.uids.smbguest;
- };
-
- users.extraGroups.smbguest.gid = config.ids.uids.smbguest;
-
system.nssModules = optional cfg.nsswins samba;
systemd = {
@@ -224,7 +193,7 @@ in
"samba-setup" = {
description = "Samba Setup Task";
script = setupScript;
- unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba";
+ unitConfig.RequiresMountsFor = "/var/samba /var/log/samba";
};
};
};
diff --git a/nixos/modules/services/network-filesystems/u9fs.nix b/nixos/modules/services/network-filesystems/u9fs.nix
new file mode 100644
index 00000000000..64809727464
--- /dev/null
+++ b/nixos/modules/services/network-filesystems/u9fs.nix
@@ -0,0 +1,75 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.u9fs;
+in
+{
+
+ options = {
+
+ services.u9fs = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to run the u9fs 9P server for Unix.";
+ };
+
+ listenStreams = mkOption {
+ type = types.listOf types.str;
+ default = [ "564" ];
+ example = [ "192.168.16.1:564" ];
+ description = ''
+ Sockets to listen for clients on.
+ See man 5 systemd.socket for socket syntax.
+ '';
+ };
+
+ extraArgs = mkOption {
+ type = types.str;
+ default = "";
+ example = "-a none -u nobody";
+ description =
+ ''
+ Extra arguments to pass on invocation,
+ see man 4 u9fs
+ '';
+ };
+
+ fsroot = mkOption {
+ type = types.path;
+ default = "/";
+ example = "/srv";
+ description = "File system root to serve to clients.";
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd = {
+ sockets.u9fs = {
+ description = "U9fs Listening Socket";
+ wantedBy = [ "sockets.target" ];
+ inherit (cfg) listenStreams;
+ socketConfig.Accept = "yes";
+ };
+ services."u9fs@" = {
+ description = "9P Protocol Server";
+ reloadIfChanged = true;
+ requires = [ "u9fs.socket" ];
+ serviceConfig =
+ { ExecStart = "-${pkgs.u9fs}/bin/u9fs ${cfg.extraArgs} ${cfg.fsroot}";
+ StandardInput = "socket";
+ StandardError = "journal";
+ };
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/network-filesystems/yandex-disk.nix b/nixos/modules/services/network-filesystems/yandex-disk.nix
new file mode 100644
index 00000000000..982b6ca5ea7
--- /dev/null
+++ b/nixos/modules/services/network-filesystems/yandex-disk.nix
@@ -0,0 +1,104 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.yandex-disk;
+
+ dir = "/var/lib/yandex-disk";
+
+ u = if cfg.user != null then cfg.user else "yandexdisk";
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.yandex-disk = {
+
+ enable = mkOption {
+ default = false;
+ description = "
+ Whether to enable Yandex-disk client. See https://disk.yandex.ru/
+ ";
+ };
+
+ username = mkOption {
+ default = "";
+ type = types.string;
+ description = ''
+ Your yandex.com login name.
+ '';
+ };
+
+ password = mkOption {
+ default = "";
+ type = types.string;
+ description = ''
+ Your yandex.com password. Warning: it will be world-readable in /nix/store.
+ '';
+ };
+
+ user = mkOption {
+ default = null;
+ description = ''
+ The user the yandex-disk daemon should run as.
+ '';
+ };
+
+ directory = mkOption {
+ default = "/home/Yandex.Disk";
+ description = "The directory to use for Yandex.Disk storage";
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ users.extraUsers = mkIf (cfg.user == null) [ {
+ name = u;
+ uid = config.ids.uids.yandexdisk;
+ group = "nogroup";
+ home = dir;
+ } ];
+
+ systemd.services.yandex-disk = {
+ description = "Yandex-disk server";
+
+ after = [ "network.target" ];
+
+ wantedBy = [ "multi-user.target" ];
+
+ # FIXME: have to specify ${directory} here as well
+ unitConfig.RequiresMountsFor = dir;
+
+ script = ''
+ mkdir -p -m 700 ${dir}
+ chown ${u} ${dir}
+
+ if ! test -d "${cfg.directory}" ; then
+ mkdir -p -m 755 ${cfg.directory} ||
+ exit 1
+ fi
+
+ ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
+ -c '${pkgs.yandex-disk}/bin/yandex-disk token -p ${cfg.password} ${cfg.username} ${dir}/token'
+
+ ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${u} \
+ -c '${pkgs.yandex-disk}/bin/yandex-disk start --no-daemon -a ${dir}/token -d ${cfg.directory}'
+ '';
+
+ };
+ };
+
+}
+
diff --git a/nixos/modules/services/networking/aiccu.nix b/nixos/modules/services/networking/aiccu.nix
new file mode 100644
index 00000000000..4301da28881
--- /dev/null
+++ b/nixos/modules/services/networking/aiccu.nix
@@ -0,0 +1,195 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.aiccu;
+ showBool = b: if b then "true" else "false";
+ notNull = a: ! isNull a;
+ configFile = pkgs.writeText "aiccu.conf" ''
+ ${if notNull cfg.username then "username " + cfg.username else ""}
+ ${if notNull cfg.password then "password " + cfg.password else ""}
+ protocol ${cfg.protocol}
+ server ${cfg.server}
+ ipv6_interface ${cfg.interfaceName}
+ verbose ${showBool cfg.verbose}
+ daemonize true
+ automatic ${showBool cfg.automatic}
+ requiretls ${showBool cfg.requireTLS}
+ pidfile ${cfg.pidFile}
+ defaultroute ${showBool cfg.defaultRoute}
+ ${if notNull cfg.setupScript then cfg.setupScript else ""}
+ makebeats ${showBool cfg.makeHeartBeats}
+ noconfigure ${showBool cfg.noConfigure}
+ behindnat ${showBool cfg.behindNAT}
+ ${if cfg.localIPv4Override then "local_ipv4_override" else ""}
+ '';
+
+in {
+
+ options = {
+
+ services.aiccu = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Enable aiccu IPv6 over IPv4 SiXXs tunnel";
+ };
+
+ username = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ example = "FAB5-SIXXS";
+ description = "Login credential";
+ };
+
+ password = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ example = "TmAkRbBEr0";
+ description = "Login credential";
+ };
+
+ protocol = mkOption {
+ type = types.str;
+ default = "tic";
+ example = "tic|tsp|l2tp";
+ description = "Protocol to use for setting up the tunnel";
+ };
+
+ server = mkOption {
+ type = types.str;
+ default = "tic.sixxs.net";
+ example = "enabled.ipv6server.net";
+ description = "Server to use for setting up the tunnel";
+ };
+
+ interfaceName = mkOption {
+ type = types.str;
+ default = "aiccu";
+ example = "sixxs";
+ description = ''
+ The name of the interface that will be used as a tunnel interface.
+ On *BSD the ipv6_interface should be set to gifX (eg gif0) for proto-41 tunnels
+ or tunX (eg tun0) for AYIYA tunnels.
+ '';
+ };
+
+ tunnelID = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ example = "T12345";
+ description = "The tunnel id to use, only required when there are multiple tunnels in the list";
+ };
+
+ verbose = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Be verbose?";
+ };
+
+ automatic = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = "Automatic Login and Tunnel activation";
+ };
+
+ requireTLS = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ When set to true, if TLS is not supported on the server
+ the TIC transaction will fail.
+ When set to false, it will try a starttls, when that is
+ not supported it will continue.
+ In any case if AICCU is build with TLS support it will
+ try to do a 'starttls' to the TIC server to see if that
+ is supported.
+ '';
+ };
+
+ pidFile = mkOption {
+ type = types.path;
+ default = "/run/aiccu.pid";
+ example = "/var/lib/aiccu/aiccu.pid";
+ description = "Location of PID File";
+ };
+
+ defaultRoute = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = "Add a default route";
+ };
+
+ setupScript = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/var/lib/aiccu/fix-subnets.sh";
+ description = "Script to run after setting up the interfaces";
+ };
+
+ makeHeartBeats = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = ''
+ In general you don't want to turn this off
+ Of course only applies to AYIYA and heartbeat tunnels not to static ones
+ '';
+ };
+
+ noConfigure = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Don't configure anything";
+ };
+
+ behindNAT = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Notify the user that a NAT-kind network is detected";
+ };
+
+ localIPv4Override = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Overrides the IPv4 parameter received from TIC
+ This allows one to configure a NAT into "DMZ" mode and then
+ forwarding the proto-41 packets to an internal host.
+
+ This is only needed for static proto-41 tunnels!
+ AYIYA and heartbeat tunnels don't require this.
+ '';
+ };
+
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.aiccu = {
+ description = "Automatic IPv6 Connectivity Client Utility";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.aiccu}/bin/aiccu start ${configFile}";
+ ExecStop = "${pkgs.aiccu}/bin/aiccu stop";
+ Type = "forking";
+ PIDFile = cfg.pidFile;
+ Restart = "no"; # aiccu startup errors are serious, do not pound the tic server or be banned.
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/networking/atftpd.nix b/nixos/modules/services/networking/atftpd.nix
new file mode 100644
index 00000000000..47465ba948a
--- /dev/null
+++ b/nixos/modules/services/networking/atftpd.nix
@@ -0,0 +1,51 @@
+# NixOS module for atftpd TFTP server
+
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.atftpd;
+
+in
+
+{
+
+ options = {
+
+ services.atftpd = {
+
+ enable = mkOption {
+ default = false;
+ type = types.uniq types.bool;
+ description = ''
+ Whenever to enable the atftpd TFTP server.
+ '';
+ };
+
+ root = mkOption {
+ default = "/var/empty";
+ type = types.uniq types.string;
+ description = ''
+ Document root directory for the atftpd.
+ '';
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.atftpd = {
+ description = "atftpd TFTP server";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ # runs as nobody
+ serviceConfig.ExecStart = "${pkgs.atftp}/sbin/atftpd --daemon --no-fork --bind-address 0.0.0.0 ${cfg.root}";
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/btsync.nix b/nixos/modules/services/networking/btsync.nix
index 5d0e17c293e..8b90f295ed4 100644
--- a/nixos/modules/services/networking/btsync.nix
+++ b/nixos/modules/services/networking/btsync.nix
@@ -4,6 +4,9 @@ with lib;
let
cfg = config.services.btsync;
+
+ bittorrentSync = cfg.package;
+
listenAddr = cfg.httpListenAddr + ":" + (toString cfg.httpListenPort);
boolStr = x: if x then "true" else "false";
@@ -57,7 +60,7 @@ let
''
{
"device_name": "${cfg.deviceName}",
- "storage_path": "/var/lib/btsync",
+ "storage_path": "${cfg.storagePath}",
"listening_port": ${toString cfg.listeningPort},
"use_gui": false,
@@ -88,7 +91,7 @@ in
use systemctl start btsync@user to start
the daemon only for user user , using the
configuration file located at
- $HOME/.config/btsync.conf
+ $HOME/.config/btsync.conf .
'';
};
@@ -195,6 +198,23 @@ in
'';
};
+ package = mkOption {
+ type = types.package;
+ example = literalExample "pkgs.bittorrentSync20";
+ description = ''
+ Branch of bittorrent sync to use.
+ '';
+ };
+
+ storagePath = mkOption {
+ type = types.path;
+ default = "/var/lib/btsync";
+ example = "/var/lib/btsync";
+ description = ''
+ Where to store the bittorrent sync files.
+ '';
+ };
+
apiKey = mkOption {
type = types.str;
default = "";
@@ -223,6 +243,21 @@ in
--generate-secret. Note that this secret will be
put inside the Nix store, so it is realistically not very
secret.
+
+ If you would like to be able to modify the contents of this
+ directories, it is recommended that you make your user a
+ member of the btsync group.
+
+ Directories in this list should be in the
+ btsync group, and that group must have
+ write access to the directory. It is also recommended that
+ chmod g+s is applied to the directory
+ so that any sub directories created will also belong to
+ the btsync group. Also,
+ setfacl -d -m group:btsync:rwx and
+ setfacl -m group:btsync:rwx should also
+ be applied so that the sub directories are writable by
+ the group.
'';
};
};
@@ -241,19 +276,27 @@ in
}
];
+ services.btsync.package = mkOptionDefault pkgs.bittorrentSync14;
+
users.extraUsers.btsync = {
description = "Bittorrent Sync Service user";
- home = "/var/lib/btsync";
+ home = cfg.storagePath;
createHome = true;
uid = config.ids.uids.btsync;
+ group = "btsync";
};
+ users.extraGroups = [
+ { name = "btsync";
+ }];
+
systemd.services.btsync = with pkgs; {
description = "Bittorrent Sync Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
Restart = "on-abort";
+ UMask = "0002";
User = "btsync";
ExecStart =
"${bittorrentSync}/bin/btsync --nodaemon --config ${configFile}";
@@ -271,6 +314,6 @@ in
};
};
- environment.systemPackages = [ pkgs.bittorrentSync ];
+ environment.systemPackages = [ cfg.package ];
};
}
diff --git a/nixos/modules/services/networking/chrony.nix b/nixos/modules/services/networking/chrony.nix
index d1684dd9f05..fe062b30e4b 100644
--- a/nixos/modules/services/networking/chrony.nix
+++ b/nixos/modules/services/networking/chrony.nix
@@ -48,9 +48,10 @@ in
servers = mkOption {
default = [
- "0.pool.ntp.org"
- "1.pool.ntp.org"
- "2.pool.ntp.org"
+ "0.nixos.pool.ntp.org"
+ "1.nixos.pool.ntp.org"
+ "2.nixos.pool.ntp.org"
+ "3.nixos.pool.ntp.org"
];
description = ''
The set of NTP servers from which to synchronise.
@@ -99,8 +100,8 @@ in
jobs.chronyd =
{ description = "chrony daemon";
- wantedBy = [ "ip-up.target" ];
- partOf = [ "ip-up.target" ];
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
path = [ chrony ];
diff --git a/nixos/modules/services/networking/cjdns-hosts.sh b/nixos/modules/services/networking/cjdns-hosts.sh
new file mode 100644
index 00000000000..8a2b47e5214
--- /dev/null
+++ b/nixos/modules/services/networking/cjdns-hosts.sh
@@ -0,0 +1,11 @@
+pubs=($pubs)
+hosts=($hosts)
+
+lines="''\n"
+for ((i = 0; i < ${#pubs[*]}; i++)); do
+ addr=$($cjdns/bin/publictoip6 ${pubs[i]})
+ lines="${lines}$addr ${hosts[i]}\n"
+done
+lines="${lines}''"
+
+echo -ne $lines > $out
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix
index 9306ffd5a18..be0acb27324 100644
--- a/nixos/modules/services/networking/cjdns.nix
+++ b/nixos/modules/services/networking/cjdns.nix
@@ -1,56 +1,78 @@
-# You may notice the commented out sections in this file,
-# it would be great to configure cjdns from nix, but cjdns
-# reads its configuration from stdin, including the private
-# key and admin password, all nested in a JSON structure.
-#
-# Until a good method of storing the keys outside the nix
-# store and mixing them back into a string is devised
-# (without too much shell hackery), a skeleton of the
-# configuration building lies commented out.
-
{ config, lib, pkgs, ... }:
with lib;
let
+ pkg = pkgs.cjdns;
+
cfg = config.services.cjdns;
- /*
- # can't keep keys and passwords in the nix store,
- # but don't want to deal with this stdin quagmire.
+ connectToSubmodule =
+ { options, ... }:
+ { options =
+ { password = mkOption {
+ type = types.str;
+ description = "Authorized password to the opposite end of the tunnel.";
+ };
+ publicKey = mkOption {
+ type = types.str;
+ description = "Public key at the opposite end of the tunnel.";
+ };
+ hostname = mkOption {
+ default = "";
+ example = "foobar.hype";
+ type = types.str;
+ description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures.";
+ };
+ };
+ };
- cjdrouteConf = '' {
- "admin": {"bind": "${cfg.admin.bind}", "password": "\${CJDNS_ADMIN}" },
- "privateKey": "\${CJDNS_KEY}",
+ peers = mapAttrsToList (n: v: v) (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo);
- "interfaces": {
- ''
+ pubs = toString (map (p: if p.hostname == "" then "" else p.publicKey) peers);
+ hosts = toString (map (p: if p.hostname == "" then "" else p.hostname) peers);
- + optionalString (cfg.interfaces.udp.bind.address != null) ''
- "UDPInterface": [ {
- "bind": "${cfg.interfaces.udp.bind.address}:"''
- ${if cfg.interfaces.upd.bind.port != null
- then ${toString cfg.interfaces.udp.bind.port}
- else ${RANDOM}
- fi)
- + '' } ]''
+ cjdnsHosts =
+ if hosts != "" then
+ import (pkgs.stdenv.mkDerivation {
+ name = "cjdns-hosts";
+ builder = ./cjdns-hosts.sh;
- + (if cfg.interfaces.eth.bind != null then ''
- "ETHInterface": [ {
- "bind": "${cfg.interfaces.eth.bind}",
- "beacon": ${toString cfg.interfaces.eth.beacon}
- } ]
- '' fi )
- + ''
- },
- "router": { "interface": { "type": "TUNInterface" }, },
- "security": [ { "setuser": "nobody" } ]
- }
- '';
+ inherit (pkgs) cjdns;
+ inherit pubs hosts;
+ })
+ else "";
+
+ # would be nice to merge 'cfg' with a //,
+ # but the json nesting is wacky.
+ cjdrouteConf = builtins.toJSON ( {
+ admin = {
+ bind = cfg.admin.bind;
+ password = "@CJDNS_ADMIN_PASSWORD@";
+ };
+ authorizedPasswords = map (p: { password = p; }) cfg.authorizedPasswords;
+ interfaces = {
+ ETHInterface = if (cfg.ETHInterface.bind != "") then [ cfg.ETHInterface ] else [ ];
+ UDPInterface = if (cfg.UDPInterface.bind != "") then [ cfg.UDPInterface ] else [ ];
+ };
+
+ privateKey = "@CJDNS_PRIVATE_KEY@";
+
+ resetAfterInactivitySeconds = 100;
+
+ router = {
+ interface = { type = "TUNInterface"; };
+ ipTunnel = {
+ allowedConnections = [];
+ outgoingConnections = [];
+ };
+ };
+
+ security = [ { exemptAngel = 1; setuser = "nobody"; } ];
+
+ });
- cjdrouteConfFile = pkgs.writeText "cjdroute.conf" cjdrouteConf
- */
in
{
@@ -60,148 +82,180 @@ in
enable = mkOption {
type = types.bool;
- default = false;
+ default = false;
description = ''
- Enable this option to start a instance of the
- cjdns network encryption and and routing engine.
- Configuration will be read from confFile .
+ Whether to enable the cjdns network encryption
+ and routing engine. A file at /etc/cjdns.keys will
+ be created if it does not exist to contain a random
+ secret key that your IPv6 address will be derived from.
'';
};
confFile = mkOption {
- default = "/etc/cjdroute.conf";
+ type = types.str;
+ default = "";
+ example = "/etc/cjdroute.conf";
description = ''
- Configuration file to pipe to cjdroute.
+ Ignore all other cjdns options and load configuration from this file.
'';
};
- /*
+ authorizedPasswords = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [
+ "snyrfgkqsc98qh1y4s5hbu0j57xw5s0"
+ "z9md3t4p45mfrjzdjurxn4wuj0d8swv"
+ "49275fut6tmzu354pq70sr5b95qq0vj"
+ ];
+ description = ''
+ Any remote cjdns nodes that offer these passwords on
+ connection will be allowed to route through this node.
+ '';
+ };
+
admin = {
bind = mkOption {
- default = "127.0.0.1:11234";
- description = ''
+ type = types.string;
+ default = "127.0.0.1:11234";
+ description = ''
Bind the administration port to this address and port.
- '';
- };
-
- passwordFile = mkOption {
- example = "/root/cjdns.adminPassword";
- description = ''
- File containing a password to the administration port.
- '';
- };
- };
-
- keyFile = mkOption {
- type = types.str;
- example = "/root/cjdns.key";
- description = ''
- Path to a file containing a cjdns private key on a single line.
- '';
- };
-
- passwordsFile = mkOption {
- type = types.str;
- default = null;
- example = "/root/cjdns.authorizedPasswords";
- description = ''
- A file containing a list of json dictionaries with passwords.
- For example:
- {"password": "s8xf5z7znl4jt05g922n3wpk75wkypk"},
- { "name": "nice guy",
- "password": "xhthk1mglz8tpjrbbvdlhyc092rhpx5"},
- {"password": "3qfxyhmrht7uwzq29pmhbdm9w4bnc8w"}
- '';
- };
-
- interfaces = {
- udp = {
- bind = {
- address = mkOption {
- default = "0.0.0.0";
- description = ''
- Address to bind UDP tunnels to; disable by setting to null;
- '';
- };
- port = mkOption {
- type = types.int;
- default = null;
- description = ''
- Port to bind UDP tunnels to.
- A port will be choosen at random if this is not set.
- This option is required to act as the server end of
- a tunnel.
- '';
- };
- };
- };
-
- eth = {
- bind = mkOption {
- default = null;
- example = "eth0";
- description = ''
- Bind to this device and operate with native wire format.
- '';
- };
-
- beacon = mkOption {
- default = 2;
- description = ''
- Auto-connect to other cjdns nodes on the same network.
- Options:
- 0 -- Disabled.
-
- 1 -- Accept beacons, this will cause cjdns to accept incoming
- beacon messages and try connecting to the sender.
-
- 2 -- Accept and send beacons, this will cause cjdns to broadcast
- messages on the local network which contain a randomly
- generated per-session password, other nodes which have this
- set to 1 or 2 will hear the beacon messages and connect
- automatically.
- '';
- };
-
- connectTo = mkOption {
- type = types.listOf types.str;
- default = [];
- description = ''
- Credentials for connecting look similar to UDP credientials
- except they begin with the mac address, for example:
- "01:02:03:04:05:06":{"password":"a","publicKey":"b"}
- '';
- };
+ '';
};
};
- */
+
+ UDPInterface = {
+ bind = mkOption {
+ type = types.string;
+ default = "";
+ example = "192.168.1.32:43211";
+ description = ''
+ Address and port to bind UDP tunnels to.
+ '';
+ };
+ connectTo = mkOption {
+ type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
+ default = { };
+ example = {
+ "192.168.1.1:27313" = {
+ hostname = "homer.hype";
+ password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+ publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
+ };
+ };
+ description = ''
+ Credentials for making UDP tunnels.
+ '';
+ };
+ };
+
+ ETHInterface = {
+ bind = mkOption {
+ default = "";
+ example = "eth0";
+ description = ''
+ Bind to this device for native ethernet operation.
+ '';
+ };
+
+ beacon = mkOption {
+ type = types.int;
+ default = 2;
+ description = ''
+ Auto-connect to other cjdns nodes on the same network.
+ Options:
+ 0: Disabled.
+ 1: Accept beacons, this will cause cjdns to accept incoming
+ beacon messages and try connecting to the sender.
+ 2: Accept and send beacons, this will cause cjdns to broadcast
+ messages on the local network which contain a randomly
+ generated per-session password, other nodes which have this
+ set to 1 or 2 will hear the beacon messages and connect
+ automatically.
+ '';
+ };
+
+ connectTo = mkOption {
+ type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
+ default = { };
+ example = {
+ "01:02:03:04:05:06" = {
+ hostname = "homer.hype";
+ password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+ publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
+ };
+ };
+ description = ''
+ Credentials for connecting look similar to UDP credientials
+ except they begin with the mac address.
+ '';
+ };
+ };
+
};
+
};
config = mkIf config.services.cjdns.enable {
boot.kernelModules = [ "tun" ];
- /*
- networking.firewall.allowedUDPPorts = mkIf (cfg.udp.bind.port != null) [
- cfg.udp.bind.port
- ];
- */
+ # networking.firewall.allowedUDPPorts = ...
systemd.services.cjdns = {
description = "encrypted networking for everybody";
- wantedBy = [ "multi-user.target" ];
- wants = [ "network.target" ];
- before = [ "network.target" ];
- path = [ pkgs.cjdns ];
+ wantedBy = [ "network.target" ];
+ after = [ "networkSetup.service" "network-interfaces.target" ];
+
+ preStart = if cfg.confFile != "" then "" else ''
+ [ -e /etc/cjdns.keys ] && source /etc/cjdns.keys
+
+ if [ -z "$CJDNS_PRIVATE_KEY" ]; then
+ shopt -s lastpipe
+ ${pkg}/bin/makekeys | { read private ipv6 public; }
+
+ umask 0077
+ echo "CJDNS_PRIVATE_KEY=$private" >> /etc/cjdns.keys
+ echo -e "CJDNS_IPV6=$ipv6\nCJDNS_PUBLIC_KEY=$public" > /etc/cjdns.public
+
+ chmod 600 /etc/cjdns.keys
+ chmod 444 /etc/cjdns.public
+ fi
+
+ if [ -z "$CJDNS_ADMIN_PASSWORD" ]; then
+ echo "CJDNS_ADMIN_PASSWORD=$(${pkgs.coreutils}/bin/head -c 96 /dev/urandom | ${pkgs.coreutils}/bin/tr -dc A-Za-z0-9)" \
+ >> /etc/cjdns.keys
+ fi
+ '';
+
+ script = (
+ if cfg.confFile != "" then "${pkg}/bin/cjdroute < ${cfg.confFile}" else
+ ''
+ source /etc/cjdns.keys
+ echo '${cjdrouteConf}' | sed \
+ -e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \
+ -e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \
+ | ${pkg}/bin/cjdroute
+ ''
+ );
serviceConfig = {
Type = "forking";
- ExecStart = ''
- ${pkgs.stdenv.shell} -c "${pkgs.cjdns}/sbin/cjdroute < ${cfg.confFile}"
- '';
- Restart = "on-failure";
+ Restart = "on-failure";
};
};
+
+ networking.extraHosts = "${cjdnsHosts}";
+
+ assertions = [
+ { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile == "" );
+ message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
+ }
+ { assertion = config.networking.enableIPv6;
+ message = "networking.enableIPv6 must be enabled for CJDNS to work";
+ }
+ ];
+
};
+
}
diff --git a/nixos/modules/services/networking/consul.nix b/nixos/modules/services/networking/consul.nix
new file mode 100644
index 00000000000..5308fd99508
--- /dev/null
+++ b/nixos/modules/services/networking/consul.nix
@@ -0,0 +1,255 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+let
+
+ dataDir = "/var/lib/consul";
+ cfg = config.services.consul;
+
+ configOptions = {
+ data_dir = dataDir;
+ }
+ // (if cfg.webUi then { ui_dir = "${pkgs.consul.ui}"; } else { })
+ // cfg.extraConfig;
+
+ configFiles = [ "/etc/consul.json" "/etc/consul-addrs.json" ]
+ ++ cfg.extraConfigFiles;
+
+ devices = attrValues (filterAttrs (_: i: i != null) cfg.interface);
+ systemdDevices = flip map devices
+ (i: "sys-subsystem-net-devices-${utils.escapeSystemdPath i}.device");
+in
+{
+ options = {
+
+ services.consul = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enables the consul daemon.
+ '';
+ };
+
+ webUi = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enables the web interface on the consul http port.
+ '';
+ };
+
+ leaveOnStop = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If enabled, causes a leave action to be sent when closing consul.
+ This allows a clean termination of the node, but permanently removes
+ it from the cluster. You probably don't want this option unless you
+ are running a node which going offline in a permanent / semi-permanent
+ fashion.
+ '';
+ };
+
+ joinNodes = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = ''
+ A list of addresses of nodes which should be joined at startup if the
+ current node is in a left state.
+ '';
+ };
+
+ joinRetries = mkOption {
+ type = types.int;
+ default = 10;
+ description = ''
+ The number of times to retry connecting to the join nodes.
+ '';
+ };
+
+ interface = {
+
+ advertise = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The name of the interface to pull the advertise_addr from.
+ '';
+ };
+
+ bind = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The name of the interface to pull the bind_addr from.
+ '';
+ };
+
+ };
+
+ forceIpv4 = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether we should force the interfaces to only pull ipv4 addresses.
+ '';
+ };
+
+ dropPrivileges = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether the consul agent should be run as a non-root consul user.
+ '';
+ };
+
+ extraConfig = mkOption {
+ default = { };
+ description = ''
+ Extra configuration options which are serialized to json and added
+ to the config.json file.
+ '';
+ };
+
+ extraConfigFiles = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ Additional configuration files to pass to consul
+ NOTE: These will not trigger the service to be restarted when altered.
+ '';
+ };
+
+ alerts = {
+ enable = mkEnableOption "Whether to enable consul-alerts";
+
+ listenAddr = mkOption {
+ description = "Api listening address.";
+ default = "localhost:9000";
+ type = types.str;
+ };
+
+ consulAddr = mkOption {
+ description = "Consul api listening adddress";
+ default = "localhost:8500";
+ type = types.str;
+ };
+
+ watchChecks = mkOption {
+ description = "Whether to enable check watcher.";
+ default = true;
+ type = types.bool;
+ };
+
+ watchEvents = mkOption {
+ description = "Whether to enable event watcher.";
+ default = true;
+ type = types.bool;
+ };
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ users.extraUsers."consul" = {
+ description = "Consul agent daemon user";
+ uid = config.ids.uids.consul;
+ };
+
+ environment = {
+ etc."consul.json".text = builtins.toJSON configOptions;
+ systemPackages = with pkgs; [ consul ];
+ };
+
+ systemd.services.consul = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ] ++ systemdDevices;
+ bindsTo = systemdDevices;
+ restartTriggers = [ config.environment.etc."consul.json".source ];
+
+ serviceConfig = {
+ ExecStart = "@${pkgs.consul}/bin/consul consul agent"
+ + concatMapStrings (n: " -config-file ${n}") configFiles;
+ ExecReload = "${pkgs.consul}/bin/consul reload";
+ PermissionsStartOnly = true;
+ User = if cfg.dropPrivileges then "consul" else null;
+ TimeoutStartSec = "0";
+ } // (optionalAttrs (cfg.leaveOnStop) {
+ ExecStop = "${pkgs.consul}/bin/consul leave";
+ });
+
+ path = with pkgs; [ iproute gnugrep gawk consul ];
+ preStart = ''
+ mkdir -m 0700 -p ${dataDir}
+ chown -R consul ${dataDir}
+
+ # Determine interface addresses
+ getAddrOnce () {
+ ip addr show dev "$1" \
+ | grep 'inet${optionalString (cfg.forceIpv4) " "}.*scope global' \
+ | awk -F '[ /\t]*' '{print $3}' | head -n 1
+ }
+ getAddr () {
+ ADDR="$(getAddrOnce $1)"
+ LEFT=60 # Die after 1 minute
+ while [ -z "$ADDR" ]; do
+ sleep 1
+ LEFT=$(expr $LEFT - 1)
+ if [ "$LEFT" -eq "0" ]; then
+ echo "Address lookup timed out"
+ exit 1
+ fi
+ ADDR="$(getAddrOnce $1)"
+ done
+ echo "$ADDR"
+ }
+ echo "{" > /etc/consul-addrs.json
+ delim=" "
+ ''
+ + concatStrings (flip mapAttrsToList cfg.interface (name: i:
+ optionalString (i != null) ''
+ echo "$delim \"${name}_addr\": \"$(getAddr "${i}")\"" >> /etc/consul-addrs.json
+ delim=","
+ ''))
+ + ''
+ echo "}" >> /etc/consul-addrs.json
+ '';
+ postStart = ''
+ # Issues joins to nodes which we statically connect to
+ ${flip concatMapStrings cfg.joinNodes (addr: ''
+ for i in {0..${toString cfg.joinRetries}}; do
+ # Try to join the other nodes ${toString cfg.joinRetries} times before failing
+ consul join "${addr}" && break
+ sleep 1
+ done &
+ '')}
+ wait
+ exit 0
+ '';
+ };
+
+ systemd.services.consul-alerts = mkIf (cfg.alerts.enable) {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "consul.service" ];
+
+ path = [ pkgs.consul ];
+
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.consul-alerts}/bin/consul-alerts start \
+ --alert-addr=${cfg.alerts.listenAddr} \
+ --consul-addr=${cfg.alerts.consulAddr} \
+ ${optionalString cfg.alerts.watchChecks "--watch-checks"} \
+ ${optionalString cfg.alerts.watchEvents "--watch-events"}
+ '';
+ User = if cfg.dropPrivileges then "consul" else null;
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix
new file mode 100644
index 00000000000..36bd29109b8
--- /dev/null
+++ b/nixos/modules/services/networking/copy-com.nix
@@ -0,0 +1,53 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.copy-com;
+
+in
+
+{
+ options = {
+
+ services.copy-com = {
+
+ enable = mkOption {
+ default = false;
+ description = "
+ Enable the copy.com client.
+
+ The first time copy.com is run, it needs to be configured. Before enabling run
+ copy_console manually.
+ ";
+ };
+
+ user = mkOption {
+ description = "The user for which copy should run.";
+ };
+
+ debug = mkOption {
+ default = false;
+ description = "Output more.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.postfix ];
+
+ systemd.services."copy-com-${cfg.user}" = {
+ description = "Copy.com Client";
+ after = [ "network.target" "local-fs.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.copy-com}/bin/copy_console ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";
+ User = "${cfg.user}";
+ };
+
+ };
+ };
+
+}
+
diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix
index bb94a8dacfa..f01deb6ee7c 100644
--- a/nixos/modules/services/networking/ddclient.nix
+++ b/nixos/modules/services/networking/ddclient.nix
@@ -3,24 +3,22 @@
let
inherit (lib) mkOption mkIf singleton;
-
inherit (pkgs) ddclient;
stateDir = "/var/spool/ddclient";
-
ddclientUser = "ddclient";
-
- ddclientFlags = "-foreground -file ${ddclientCfg}";
-
+ ddclientFlags = "-foreground -verbose -noquiet -file ${ddclientCfg}";
+ ddclientPIDFile = "${stateDir}/ddclient.pid";
ddclientCfg = pkgs.writeText "ddclient.conf" ''
daemon=600
cache=${stateDir}/ddclient.cache
- pid=${stateDir}/ddclient.pid
- use=${config.services.ddclient.web}
+ pid=${ddclientPIDFile}
+ use=${config.services.ddclient.use}
login=${config.services.ddclient.username}
password=${config.services.ddclient.password}
protocol=${config.services.ddclient.protocol}
server=${config.services.ddclient.server}
+ ssl=${if config.services.ddclient.ssl then "yes" else "yes"}
wildcard=YES
${config.services.ddclient.domain}
${config.services.ddclient.extraConfig}
@@ -34,10 +32,11 @@ in
options = {
- services.ddclient = {
+ services.ddclient = with lib.types; {
enable = mkOption {
default = false;
+ type = bool;
description = ''
Whether to synchronise your machine's IP address with a dynamic DNS provider (e.g. dyndns.org).
'';
@@ -45,6 +44,7 @@ in
domain = mkOption {
default = "";
+ type = str;
description = ''
Domain name to synchronize.
'';
@@ -52,76 +52,93 @@ in
username = mkOption {
default = "";
+ type = str;
description = ''
Username.
'';
};
password = mkOption {
- default = "" ;
+ default = "";
+ type = str;
description = ''
Password.
'';
};
protocol = mkOption {
- default = "dyndns2" ;
+ default = "dyndns2";
+ type = str;
description = ''
- Protocol to use with dynamic DNS provider. (see also, http://sourceforge.net/apps/trac/ddclient/wiki/Protocols)
+ Protocol to use with dynamic DNS provider (see http://sourceforge.net/apps/trac/ddclient/wiki/Protocols).
'';
};
server = mkOption {
- default = "members.dyndns.org" ;
+ default = "";
+ type = str;
description = ''
- Server
+ Server address.
+ '';
+ };
+
+ ssl = mkOption {
+ default = true;
+ type = bool;
+ description = ''
+ Whether to use to use SSL/TLS to connect to dynamic DNS provider.
'';
};
extraConfig = mkOption {
- default = "" ;
+ default = "";
+ type = str;
description = ''
Extra configuration. Contents will be added verbatim to the configuration file.
'';
};
- web = mkOption {
- default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '" ;
- description = "";
+ use = mkOption {
+ default = "web, web=checkip.dyndns.com/, web-skip='Current IP Address: '";
+ type = str;
+ description = ''
+ Method to determine the IP address to send to the dymanic DNS provider.
+ '';
};
-
};
-
};
###### implementation
config = mkIf config.services.ddclient.enable {
-
+
environment.systemPackages = [ ddclient ];
- users.extraUsers = singleton
- { name = ddclientUser;
- uid = config.ids.uids.ddclient;
- description = "ddclient daemon user";
- home = stateDir;
+ users.extraUsers = singleton {
+ name = ddclientUser;
+ uid = config.ids.uids.ddclient;
+ description = "ddclient daemon user";
+ home = stateDir;
+ };
+
+ systemd.services.ddclient = {
+ description = "Dynamic DNS Client";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ # This may change back to forking if too many problems occur:
+ type = "simple";
+ User = ddclientUser;
+ Group = "nogroup"; #TODO get this to work
+ PermissionsStartOnly = "true";
+ PIDFile = ddclientPIDFile;
+ ExecStartPre = ''
+ ${pkgs.stdenv.shell} -c "${pkgs.coreutils}/bin/mkdir -m 0755 -p ${stateDir} && ${pkgs.coreutils}/bin/chown ${ddclientUser} ${stateDir}"
+ '';
+ ExecStart = "${ddclient}/bin/ddclient ${ddclientFlags}";
+ #ExecStartPost = "${pkgs.coreutils}/bin/rm -r ${stateDir}"; # Should we have this?
};
-
- jobs.ddclient =
- { name = "ddclient";
-
- startOn = "startup";
-
- preStart =
- ''
- mkdir -m 0755 -p ${stateDir}
- chown ${ddclientUser} ${stateDir}
- '';
-
- exec = "${ddclient}/bin/ddclient ${ddclientFlags}";
- };
-
+ };
};
-
}
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index 89aa9bdb6b6..8552395fdb1 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -8,15 +8,29 @@ let
cfg = config.networking.dhcpcd;
+ interfaces = attrValues config.networking.interfaces;
+
+ enableDHCP = config.networking.useDHCP || any (i: i.useDHCP == true) interfaces;
+
# Don't start dhcpcd on explicitly configured interfaces or on
# interfaces that are part of a bridge, bond or sit device.
ignoredInterfaces =
- map (i: i.name) (filter (i: i.ipAddress != null) (attrValues config.networking.interfaces))
+ map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ip4 != [ ] || i.ipAddress != null) interfaces)
++ mapAttrsToList (i: _: i) config.networking.sits
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds))
++ config.networking.dhcpcd.denyInterfaces;
+ arrayAppendOrNull = a1: a2: if a1 == null && a2 == null then null
+ else if a1 == null then a2 else if a2 == null then a1
+ else a1 ++ a2;
+
+ # If dhcp is disabled but explicit interfaces are enabled,
+ # we need to provide dhcp just for those interfaces.
+ allowInterfaces = arrayAppendOrNull cfg.allowInterfaces
+ (if !config.networking.useDHCP && enableDHCP then
+ map (i: i.name) (filter (i: i.useDHCP == true) interfaces) else null);
+
# Config file adapted from the one that ships with dhcpcd.
dhcpcdConf = pkgs.writeText "dhcpcd.conf"
''
@@ -41,7 +55,7 @@ let
denyinterfaces ${toString ignoredInterfaces} lo peth* vif* tap* tun* virbr* vnet* vboxnet* sit*
# Use the list of allowed interfaces if specified
- ${optionalString (cfg.allowInterfaces != null) "allowinterfaces ${toString cfg.allowInterfaces}"}
+ ${optionalString (allowInterfaces != null) "allowinterfaces ${toString allowInterfaces}"}
${cfg.extraConfig}
'';
@@ -54,8 +68,10 @@ let
# will actually do something: if ntpd cannot resolve the
# server hostnames in its config file, then it will never do
# anything ever again ("couldn't resolve ..., giving up on
- # it"), so we silently lose time synchronisation.
+ # it"), so we silently lose time synchronisation. This also
+ # applies to openntpd.
${config.systemd.package}/bin/systemctl try-restart ntpd.service
+ ${config.systemd.package}/bin/systemctl try-restart openntpd.service
${config.systemd.package}/bin/systemctl start ip-up.target
fi
@@ -64,7 +80,7 @@ let
# ${config.systemd.package}/bin/systemctl start ip-down.target
#fi
- ${config.networking.dhcpcd.runHook}
+ ${cfg.runHook}
'';
in
@@ -75,6 +91,18 @@ in
options = {
+ networking.dhcpcd.persistent = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whenever to leave interfaces configured on dhcpcd daemon
+ shutdown. Set to true if you have your root or store mounted
+ over the network or this machine accepts SSH connections
+ through DHCP interfaces and clients should be notified when
+ it shuts down.
+ '';
+ };
+
networking.dhcpcd.denyInterfaces = mkOption {
type = types.listOf types.str;
default = [];
@@ -120,12 +148,15 @@ in
###### implementation
- config = mkIf config.networking.useDHCP {
+ config = mkIf enableDHCP {
systemd.services.dhcpcd =
{ description = "DHCP Client";
wantedBy = [ "network.target" ];
+ # Work-around to deal with problems where the kernel would remove &
+ # re-create Wifi interfaces early during boot.
+ after = [ "network-interfaces.target" ];
# Stopping dhcpcd during a reconfiguration is undesirable
# because it brings down the network interfaces configured by
@@ -139,7 +170,7 @@ in
serviceConfig =
{ Type = "forking";
PIDFile = "/run/dhcpcd.pid";
- ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --quiet --config ${dhcpcdConf}";
+ ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --quiet ${optionalString cfg.persistent "--persistent"} --config ${dhcpcdConf}";
ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
Restart = "always";
};
@@ -153,7 +184,7 @@ in
}
];
- powerManagement.resumeCommands =
+ powerManagement.resumeCommands = mkIf config.systemd.services.dhcpcd.enable
''
# Tell dhcpcd to rebind its interfaces if it's running.
${config.systemd.package}/bin/systemctl reload dhcpcd.service
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix
new file mode 100644
index 00000000000..5cc33f35adb
--- /dev/null
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -0,0 +1,139 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+ apparmorEnabled = config.security.apparmor.enable;
+ dnscrypt-proxy = pkgs.dnscrypt-proxy;
+ cfg = config.services.dnscrypt-proxy;
+ uid = config.ids.uids.dnscrypt-proxy;
+ daemonArgs =
+ [ "--daemonize"
+ "--user=dnscrypt-proxy"
+ "--local-address=${cfg.localAddress}:${toString cfg.port}"
+ (optionalString cfg.tcpOnly "--tcp-only")
+ "--resolvers-list=${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"
+ "--resolver-name=${cfg.resolverName}"
+ ];
+in
+
+{
+ ##### interface
+
+ options = {
+
+ services.dnscrypt-proxy = {
+
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Enable dnscrypt-proxy.
+ The proxy relays regular DNS queries to a DNSCrypt enabled
+ upstream resolver.
+ The traffic between the client and the upstream resolver is
+ encrypted and authenticated, which may mitigate the risk of MITM
+ attacks and third-party snooping (assuming the upstream is
+ trustworthy).
+ '';
+ };
+
+ localAddress = mkOption {
+ default = "127.0.0.1";
+ type = types.string;
+ description = ''
+ Listen for DNS queries on this address.
+ '';
+ };
+
+ port = mkOption {
+ default = 53;
+ type = types.int;
+ description = ''
+ Listen on this port.
+ '';
+ };
+
+ resolverName = mkOption {
+ default = "opendns";
+ type = types.string;
+ description = ''
+ The name of the upstream DNSCrypt resolver to use.
+ See ${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv
+ for alternative resolvers (e.g., if you are concerned about logging
+ and/or server location).
+ '';
+ };
+
+ tcpOnly = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Force sending encrypted DNS queries to the upstream resolver
+ over TCP instead of UDP (on port 443).
+ Enabling this option may help circumvent filtering, but should
+ not be used otherwise.
+ '';
+ };
+
+ };
+
+ };
+
+ ##### implementation
+
+ config = mkIf cfg.enable {
+
+ ### AppArmor profile
+
+ security.apparmor.profiles = mkIf apparmorEnabled [
+ (pkgs.writeText "apparmor-dnscrypt-proxy" ''
+
+ ${dnscrypt-proxy}/bin/dnscrypt-proxy {
+ network inet stream,
+ network inet6 stream,
+ network inet dgram,
+ network inet6 dgram,
+
+ capability ipc_lock,
+ capability net_bind_service,
+ capability net_admin,
+ capability sys_chroot,
+ capability setgid,
+ capability setuid,
+
+ /dev/null rw,
+ /dev/urandom r,
+
+ ${pkgs.glibc}/lib/*.so mr,
+ ${pkgs.tzdata}/share/zoneinfo/** r,
+
+ ${dnscrypt-proxy}/share/dnscrypt-proxy/** r,
+ ${pkgs.gcc.cc}/lib/libssp.so.* mr,
+ ${pkgs.libsodium}/lib/libsodium.so.* mr,
+ }
+ '')
+ ];
+
+ ### User
+
+ users.extraUsers = singleton {
+ inherit uid;
+ name = "dnscrypt-proxy";
+ description = "dnscrypt-proxy daemon user";
+ };
+
+ ### Service definition
+
+ systemd.services.dnscrypt-proxy = {
+ description = "dnscrypt-proxy daemon";
+ after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
+ requires = mkIf apparmorEnabled [ "apparmor.service" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix
index d2a8af6ac8b..7ddabf73106 100644
--- a/nixos/modules/services/networking/dnsmasq.nix
+++ b/nixos/modules/services/networking/dnsmasq.nix
@@ -11,7 +11,10 @@ let
conf-file=/etc/dnsmasq-conf.conf
resolv-file=/etc/dnsmasq-resolv.conf
''}
- ${cfg.extraConfig}
+ ${flip concatMapStrings cfg.servers (server: ''
+ server=${server}
+ '')}
+ ${cfg.extraConfig}
'';
in
@@ -43,12 +46,10 @@ in
default = [];
example = [ "8.8.8.8" "8.8.4.4" ];
description = ''
- The parameter to dnsmasq -S.
+ The DNS servers which dnsmasq should query.
'';
};
-
-
extraConfig = mkOption {
type = types.string;
default = "";
@@ -67,8 +68,8 @@ in
config = mkIf config.services.dnsmasq.enable {
- environment.systemPackages = [ dnsmasq ]
- ++ (if cfg.resolveLocalQueries then [ pkgs.openresolv ] else []);
+ networking.nameservers =
+ optional cfg.resolveLocalQueries "127.0.0.1";
services.dbus.packages = [ dnsmasq ];
@@ -81,12 +82,16 @@ in
systemd.services.dnsmasq = {
description = "dnsmasq daemon";
- after = [ "network.target" ];
+ after = [ "network.target" "systemd-resolved.service" ];
wantedBy = [ "multi-user.target" ];
+ path = [ dnsmasq ];
+ preStart = ''
+ touch /etc/dnsmasq-{conf,resolv}.conf
+ dnsmasq --test
+ '';
serviceConfig = {
Type = "dbus";
BusName = "uk.org.thekelleys.dnsmasq";
- ExecStartPre = "${dnsmasq}/bin/dnsmasq --test";
ExecStart = "${dnsmasq}/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C ${dnsmasqConf}";
ExecReload = "${dnsmasq}/bin/kill -HUP $MAINPID";
};
diff --git a/nixos/modules/services/networking/firefox/sync-server.nix b/nixos/modules/services/networking/firefox/sync-server.nix
new file mode 100644
index 00000000000..79f32f3358c
--- /dev/null
+++ b/nixos/modules/services/networking/firefox/sync-server.nix
@@ -0,0 +1,142 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.firefox.syncserver;
+ syncServerIni = pkgs.writeText "syncserver.ini" ''
+ [DEFAULT]
+ overrides = ${cfg.privateConfig}
+
+ [server:main]
+ use = egg:Paste#http
+ host = ${cfg.listen.address}
+ port = ${toString cfg.listen.port}
+
+ [app:main]
+ use = egg:syncserver
+
+ [syncserver]
+ public_url = ${cfg.publicUrl}
+ ${optionalString (cfg.sqlUri != "") "sqluri = ${cfg.sqlUri}"}
+ allow_new_users = ${if cfg.allowNewUsers then "true" else "false"}
+
+ [browserid]
+ backend = tokenserver.verifiers.LocalVerifier
+ audiences = ${removeSuffix "/" cfg.publicUrl}
+ '';
+in
+
+{
+ options = {
+ services.firefox.syncserver = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Whether to enable a Firefox Sync Server, this give the opportunity to
+ Firefox users to store all synchronized data on their own server. To use this
+ server, Firefox users should visit the about:config , and
+ replicate the following change
+
+
+ services.sync.tokenServerURI: http://localhost:5000/token/1.0/sync/1.5
+
+
+ where http://localhost:5000/ corresponds to the
+ public url of the server.
+ '';
+ };
+
+ listen.address = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ example = "0.0.0.0";
+ description = ''
+ Address on which the sync server listen to.
+ '';
+ };
+
+ listen.port = mkOption {
+ type = types.int;
+ default = 5000;
+ description = ''
+ Port on which the sync server listen to.
+ '';
+ };
+
+ publicUrl = mkOption {
+ type = types.str;
+ default = "http://localhost:5000/";
+ example = "http://sync.example.com/";
+ description = ''
+ Public URL with which firefox users can use to access the sync server.
+ '';
+ };
+
+ allowNewUsers = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = ''
+ Whether to allow new-user signups on the server. Only request by
+ existing accounts will be honored.
+ '';
+ };
+
+ sqlUri = mkOption {
+ type = types.str;
+ default = "sqlite:////var/db/firefox-sync-server.db";
+ example = "postgresql://scott:tiger@localhost/test";
+ description = ''
+ The location of the database. This URL is composed of
+ dialect[+driver]://user:password@host/dbname[?key=value..] ,
+ where dialect is a database name such as
+ mysql , oracle , postgresql ,
+ etc., and driver the name of a DBAPI, such as
+ psycopg2 , pyodbc , cx_oracle ,
+ etc. The
+ SQLAlchemy documentation provides more examples and describe the syntax of
+ the expected URL.
+ '';
+ };
+
+ privateConfig = mkOption {
+ type = types.str;
+ default = "/etc/firefox/syncserver-secret.ini";
+ description = ''
+ The private config file is used to extend the generated config with confidential
+ information, such as the syncserver.sqlUri setting if it contains a
+ password, and the syncserver.secret setting is used by the server to
+ generate cryptographically-signed authentication tokens.
+
+ If this file does not exists, then it is created with a generated
+ syncserver.secret settings.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.syncserver = {
+ after = [ "network.target" ];
+ description = "Firefox Sync Server";
+ wantedBy = [ "multi-user.target" ];
+ path = [ pkgs.pythonPackages.pasteScript pkgs.coreutils ];
+ environment.PYTHONPATH = "${pkgs.pythonPackages.syncserver}/lib/${pkgs.pythonPackages.python.libPrefix}/site-packages";
+ preStart = ''
+ if ! test -e ${cfg.privateConfig}; then
+ umask u=rwx,g=x,o=x
+ mkdir -p $(dirname ${cfg.privateConfig})
+ echo > ${cfg.privateConfig} '[syncserver]'
+ echo >> ${cfg.privateConfig} "secret = $(head -c 20 /dev/urandom | sha1sum | tr -d ' -')"
+ fi
+ '';
+ serviceConfig.ExecStart = "paster serve ${syncServerIni}";
+ };
+
+ };
+}
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 42914bfe5d6..b05a640e11f 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -37,6 +37,186 @@ let
}
'';
+ writeShScript = name: text: let dir = pkgs.writeScriptBin name ''
+ #! ${pkgs.stdenv.shell} -e
+ ${text}
+ ''; in "${dir}/bin/${name}";
+
+ startScript = writeShScript "firewall-start" ''
+ ${helpers}
+
+ # Flush the old firewall rules. !!! Ideally, updating the
+ # firewall would be atomic. Apparently that's possible
+ # with iptables-restore.
+ ip46tables -D INPUT -j nixos-fw 2> /dev/null || true
+ for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do
+ ip46tables -F "$chain" 2> /dev/null || true
+ ip46tables -X "$chain" 2> /dev/null || true
+ done
+
+
+ # The "nixos-fw-accept" chain just accepts packets.
+ ip46tables -N nixos-fw-accept
+ ip46tables -A nixos-fw-accept -j ACCEPT
+
+
+ # The "nixos-fw-refuse" chain rejects or drops packets.
+ ip46tables -N nixos-fw-refuse
+
+ ${if cfg.rejectPackets then ''
+ # Send a reset for existing TCP connections that we've
+ # somehow forgotten about. Send ICMP "port unreachable"
+ # for everything else.
+ ip46tables -A nixos-fw-refuse -p tcp ! --syn -j REJECT --reject-with tcp-reset
+ ip46tables -A nixos-fw-refuse -j REJECT
+ '' else ''
+ ip46tables -A nixos-fw-refuse -j DROP
+ ''}
+
+
+ # The "nixos-fw-log-refuse" chain performs logging, then
+ # jumps to the "nixos-fw-refuse" chain.
+ ip46tables -N nixos-fw-log-refuse
+
+ ${optionalString cfg.logRefusedConnections ''
+ ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: "
+ ''}
+ ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) ''
+ ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \
+ -j LOG --log-level info --log-prefix "rejected broadcast: "
+ ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \
+ -j LOG --log-level info --log-prefix "rejected multicast: "
+ ''}
+ ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse
+ ${optionalString cfg.logRefusedPackets ''
+ ip46tables -A nixos-fw-log-refuse \
+ -j LOG --log-level info --log-prefix "rejected packet: "
+ ''}
+ ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse
+
+
+ # The "nixos-fw" chain does the actual work.
+ ip46tables -N nixos-fw
+
+ # Perform a reverse-path test to refuse spoofers
+ # For now, we just drop, as the raw table doesn't have a log-refuse yet
+ ${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
+ if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then
+ echo "<2>failed to initialise rpfilter support" >&2
+ fi
+ ''}
+
+ # Accept all traffic on the trusted interfaces.
+ ${flip concatMapStrings cfg.trustedInterfaces (iface: ''
+ ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept
+ '')}
+
+ # Accept packets from established or related connections.
+ ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
+
+ # Accept connections to the allowed TCP ports.
+ ${concatMapStrings (port:
+ ''
+ ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept
+ ''
+ ) cfg.allowedTCPPorts
+ }
+
+ # Accept connections to the allowed TCP port ranges.
+ ${concatMapStrings (rangeAttr:
+ let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
+ ''
+ ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept
+ ''
+ ) cfg.allowedTCPPortRanges
+ }
+
+ # Accept packets on the allowed UDP ports.
+ ${concatMapStrings (port:
+ ''
+ ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept
+ ''
+ ) cfg.allowedUDPPorts
+ }
+
+ # Accept packets on the allowed UDP port ranges.
+ ${concatMapStrings (rangeAttr:
+ let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
+ ''
+ ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept
+ ''
+ ) cfg.allowedUDPPortRanges
+ }
+
+ # Accept IPv4 multicast. Not a big security risk since
+ # probably nobody is listening anyway.
+ #iptables -A nixos-fw -d 224.0.0.0/4 -j nixos-fw-accept
+
+ # Optionally respond to ICMPv4 pings.
+ ${optionalString cfg.allowPing ''
+ iptables -w -A nixos-fw -p icmp --icmp-type echo-request ${optionalString (cfg.pingLimit != null)
+ "-m limit ${cfg.pingLimit} "
+ }-j nixos-fw-accept
+ ''}
+
+ # Accept all ICMPv6 messages except redirects and node
+ # information queries (type 139). See RFC 4890, section
+ # 4.4.
+ ${optionalString config.networking.enableIPv6 ''
+ ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
+ ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
+ ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
+ ''}
+
+ ${cfg.extraCommands}
+
+ # Reject/drop everything else.
+ ip46tables -A nixos-fw -j nixos-fw-log-refuse
+
+
+ # Enable the firewall.
+ ip46tables -A INPUT -j nixos-fw
+ '';
+
+ stopScript = writeShScript "firewall-stop" ''
+ ${helpers}
+
+ # Clean up in case reload fails
+ ip46tables -D INPUT -j nixos-drop 2>/dev/null || true
+
+ # Clean up after added ruleset
+ ip46tables -D INPUT -j nixos-fw 2>/dev/null || true
+
+ ${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
+ if ! ip46tables -D PREROUTING -t raw -m rpfilter --invert -j DROP; then
+ echo "<2>failed to stop rpfilter support" >&2
+ fi
+ ''}
+
+ ${cfg.extraStopCommands}
+ '';
+
+ reloadScript = writeShScript "firewall-reload" ''
+ ${helpers}
+
+ # Create a unique drop rule
+ ip46tables -D INPUT -j nixos-drop 2>/dev/null || true
+ ip46tables -F nixos-drop 2>/dev/null || true
+ ip46tables -X nixos-drop 2>/dev/null || true
+ ip46tables -N nixos-drop
+ ip46tables -A nixos-drop -j DROP
+
+ # Don't allow traffic to leak out until the script has completed
+ ip46tables -A INPUT -j nixos-drop
+ if ${startScript}; then
+ ip46tables -D INPUT -j nixos-drop 2>/dev/null || true
+ else
+ echo "Failed to reload firewall... Stopping"
+ ${stopScript}
+ exit 1
+ fi
+ '';
+
kernelPackages = config.boot.kernelPackages;
kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
@@ -176,7 +356,7 @@ in
''
If pings are allowed, this allows setting rate limits
on them. If non-null, this option should be in the form
- of flags like "-limit 1/minute -limit-burst 5"
+ of flags like "--limit 1/minute --limit-burst 5"
'';
};
@@ -240,6 +420,18 @@ in
'';
};
+ networking.firewall.extraStopCommands = mkOption {
+ type = types.lines;
+ default = "";
+ example = "iptables -P INPUT ACCEPT";
+ description =
+ ''
+ Additional shell commands executed as part of the firewall
+ shutdown script. These are executed just after the removal
+ of the nixos input rule, or if the service enters a failed state.
+ '';
+ };
+
};
@@ -251,7 +443,7 @@ in
networking.firewall.trustedInterfaces = [ "lo" ];
- environment.systemPackages = [ pkgs.iptables ];
+ environment.systemPackages = [ pkgs.iptables pkgs.ipset ];
boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
@@ -264,166 +456,29 @@ in
message = "This kernel does not support disabling conntrack helpers"; }
];
- systemd.services.firewall =
- { description = "Firewall";
+ systemd.services.firewall = {
+ description = "Firewall";
+ wantedBy = [ "network-pre.target" ];
+ before = [ "network-pre.target" ];
+ after = [ "systemd-modules-load.service" ];
- wantedBy = [ "network.target" ];
- after = [ "network-interfaces.target" "systemd-modules-load.service" ];
+ path = [ pkgs.iptables pkgs.ipset ];
- path = [ pkgs.iptables ];
+ # FIXME: this module may also try to load kernel modules, but
+ # containers don't have CAP_SYS_MODULE. So the host system had
+ # better have all necessary modules already loaded.
+ unitConfig.ConditionCapability = "CAP_NET_ADMIN";
- # FIXME: this module may also try to load kernel modules, but
- # containers don't have CAP_SYS_MODULE. So the host system had
- # better have all necessary modules already loaded.
- unitConfig.ConditionCapability = "CAP_NET_ADMIN";
+ reloadIfChanged = true;
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
-
- script =
- ''
- ${helpers}
-
- # Flush the old firewall rules. !!! Ideally, updating the
- # firewall would be atomic. Apparently that's possible
- # with iptables-restore.
- ip46tables -D INPUT -j nixos-fw 2> /dev/null || true
- for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do
- ip46tables -F "$chain" 2> /dev/null || true
- ip46tables -X "$chain" 2> /dev/null || true
- done
-
-
- # The "nixos-fw-accept" chain just accepts packets.
- ip46tables -N nixos-fw-accept
- ip46tables -A nixos-fw-accept -j ACCEPT
-
-
- # The "nixos-fw-refuse" chain rejects or drops packets.
- ip46tables -N nixos-fw-refuse
-
- ${if cfg.rejectPackets then ''
- # Send a reset for existing TCP connections that we've
- # somehow forgotten about. Send ICMP "port unreachable"
- # for everything else.
- ip46tables -A nixos-fw-refuse -p tcp ! --syn -j REJECT --reject-with tcp-reset
- ip46tables -A nixos-fw-refuse -j REJECT
- '' else ''
- ip46tables -A nixos-fw-refuse -j DROP
- ''}
-
-
- # The "nixos-fw-log-refuse" chain performs logging, then
- # jumps to the "nixos-fw-refuse" chain.
- ip46tables -N nixos-fw-log-refuse
-
- ${optionalString cfg.logRefusedConnections ''
- ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: "
- ''}
- ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) ''
- ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \
- -j LOG --log-level info --log-prefix "rejected broadcast: "
- ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \
- -j LOG --log-level info --log-prefix "rejected multicast: "
- ''}
- ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse
- ${optionalString cfg.logRefusedPackets ''
- ip46tables -A nixos-fw-log-refuse \
- -j LOG --log-level info --log-prefix "rejected packet: "
- ''}
- ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse
-
-
- # The "nixos-fw" chain does the actual work.
- ip46tables -N nixos-fw
-
- # Perform a reverse-path test to refuse spoofers
- # For now, we just drop, as the raw table doesn't have a log-refuse yet
- ${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
- if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then
- echo "<2>failed to initialise rpfilter support" >&2
- fi
- ''}
-
- # Accept all traffic on the trusted interfaces.
- ${flip concatMapStrings cfg.trustedInterfaces (iface: ''
- ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept
- '')}
-
- # Accept packets from established or related connections.
- ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
-
- # Accept connections to the allowed TCP ports.
- ${concatMapStrings (port:
- ''
- ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept
- ''
- ) cfg.allowedTCPPorts
- }
-
- # Accept connections to the allowed TCP port ranges.
- ${concatMapStrings (rangeAttr:
- let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
- ''
- ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept
- ''
- ) cfg.allowedTCPPortRanges
- }
-
- # Accept packets on the allowed UDP ports.
- ${concatMapStrings (port:
- ''
- ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept
- ''
- ) cfg.allowedUDPPorts
- }
-
- # Accept packets on the allowed UDP port ranges.
- ${concatMapStrings (rangeAttr:
- let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
- ''
- ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept
- ''
- ) cfg.allowedUDPPortRanges
- }
-
- # Accept IPv4 multicast. Not a big security risk since
- # probably nobody is listening anyway.
- #iptables -A nixos-fw -d 224.0.0.0/4 -j nixos-fw-accept
-
- # Optionally respond to ICMPv4 pings.
- ${optionalString cfg.allowPing ''
- iptables -w -A nixos-fw -p icmp --icmp-type echo-request ${optionalString (cfg.pingLimit != null)
- "-m limit ${cfg.pingLimit} "
- }-j nixos-fw-accept
- ''}
-
- # Accept all ICMPv6 messages except redirects and node
- # information queries (type 139). See RFC 4890, section
- # 4.4.
- ${optionalString config.networking.enableIPv6 ''
- ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP
- ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP
- ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept
- ''}
-
- ${cfg.extraCommands}
-
- # Reject/drop everything else.
- ip46tables -A nixos-fw -j nixos-fw-log-refuse
-
-
- # Enable the firewall.
- ip46tables -A INPUT -j nixos-fw
- '';
-
- postStop =
- ''
- ${helpers}
- ip46tables -D INPUT -j nixos-fw || true
- #ip46tables -P INPUT ACCEPT
- '';
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "@${startScript} firewall-start";
+ ExecReload = "@${reloadScript} firewall-reload";
+ ExecStop = "@${stopScript} firewall-stop";
};
+ };
};
diff --git a/nixos/modules/services/networking/git-daemon.nix b/nixos/modules/services/networking/git-daemon.nix
index 5864efaca51..566936a7d0f 100644
--- a/nixos/modules/services/networking/git-daemon.nix
+++ b/nixos/modules/services/networking/git-daemon.nix
@@ -3,7 +3,6 @@ with lib;
let
cfg = config.services.gitDaemon;
- gitUser = "git";
in
{
@@ -14,6 +13,7 @@ in
services.gitDaemon = {
enable = mkOption {
+ type = types.bool;
default = false;
description = ''
Enable Git daemon, which allows public hosting of git repositories
@@ -28,6 +28,7 @@ in
};
basePath = mkOption {
+ type = types.str;
default = "";
example = "/srv/git/";
description = ''
@@ -38,6 +39,7 @@ in
};
exportAll = mkOption {
+ type = types.bool;
default = false;
description = ''
Publish all directories that look like Git repositories (have the objects
@@ -52,6 +54,7 @@ in
};
repositories = mkOption {
+ type = types.listOf types.str;
default = [];
example = [ "/srv/git" "/home/user/git/repo2" ];
description = ''
@@ -64,21 +67,36 @@ in
};
listenAddress = mkOption {
+ type = types.str;
default = "";
example = "example.com";
description = "Listen on a specific IP address or hostname.";
};
port = mkOption {
+ type = types.int;
default = 9418;
description = "Port to listen on.";
};
options = mkOption {
+ type = types.str;
default = "";
description = "Extra configuration options to be passed to Git daemon.";
};
+ user = mkOption {
+ type = types.str;
+ default = "git";
+ description = "User under which Git daemon would be running.";
+ };
+
+ group = mkOption {
+ type = types.str;
+ default = "git";
+ description = "Group under which Git daemon would be running.";
+ };
+
};
};
@@ -86,14 +104,14 @@ in
config = mkIf cfg.enable {
- users.extraUsers = singleton
- { name = gitUser;
+ users.extraUsers = if cfg.user != "git" then {} else singleton
+ { name = "git";
uid = config.ids.uids.git;
description = "Git daemon user";
};
- users.extraGroups = singleton
- { name = gitUser;
+ users.extraGroups = if cfg.group != "git" then {} else singleton
+ { name = "git";
gid = config.ids.gids.git;
};
@@ -103,8 +121,8 @@ in
exec = "${pkgs.git}/bin/git daemon --reuseaddr "
+ (optionalString (cfg.basePath != "") "--base-path=${cfg.basePath} ")
+ (optionalString (cfg.listenAddress != "") "--listen=${cfg.listenAddress} ")
- + "--port=${toString cfg.port} --user=${gitUser} --group=${gitUser} ${cfg.options} "
- + "--verbose " + (optionalString cfg.exportAll "--export-all") + concatStringsSep " " cfg.repositories;
+ + "--port=${toString cfg.port} --user=${cfg.user} --group=${cfg.group} ${cfg.options} "
+ + "--verbose " + (optionalString cfg.exportAll "--export-all ") + concatStringsSep " " cfg.repositories;
};
};
diff --git a/nixos/modules/services/networking/gogoclient.nix b/nixos/modules/services/networking/gogoclient.nix
index 41600794197..9d16f0efb43 100644
--- a/nixos/modules/services/networking/gogoclient.nix
+++ b/nixos/modules/services/networking/gogoclient.nix
@@ -76,8 +76,7 @@ in
exec ${pkgs.gogoclient}/bin/gogoc -y -f /var/lib/gogoc/gogoc.conf
'';
} // optionalAttrs cfg.autorun {
- wantedBy = [ "ip-up.target" ];
- partOf = [ "ip-up.target" ];
+ wantedBy = [ "multi-user.target" ];
};
};
diff --git a/nixos/modules/services/networking/haproxy.nix b/nixos/modules/services/networking/haproxy.nix
index c2e2c2d7a41..09e48ec4bff 100644
--- a/nixos/modules/services/networking/haproxy.nix
+++ b/nixos/modules/services/networking/haproxy.nix
@@ -9,51 +9,21 @@ with lib;
services.haproxy = {
enable = mkOption {
+ type = types.bool;
default = false;
- description = "
- Enable the HAProxy.
- ";
+ description = ''
+ Whether to enable HAProxy, the reliable, high performance TCP/HTTP
+ load balancer.
+ '';
};
config = mkOption {
- default =
- ''
- global
- log 127.0.0.1 local6
- maxconn 24000
- daemon
- nbproc 1
-
- defaults
- mode http
- option httpclose
-
- # Remove requests from the queue if people press stop button
- option abortonclose
-
- # Try to connect this many times on failure
- retries 3
-
- # If a client is bound to a particular backend but it goes down,
- # send them to a different one
- option redispatch
-
- monitor-uri /haproxy-ping
-
- timeout connect 7s
- timeout queue 300s
- timeout client 300s
- timeout server 300s
-
- # Enable status page at this URL, on the port HAProxy is bound to
- stats enable
- stats uri /haproxy-status
- stats refresh 5s
- stats realm Haproxy statistics
- '';
- description = "
- Default configuration.
- ";
+ type = types.nullOr types.lines;
+ default = null;
+ description = ''
+ Contents of the HAProxy configuration file,
+ haproxy.conf .
+ '';
};
};
@@ -62,16 +32,21 @@ with lib;
config = mkIf cfg.enable {
+ assertions = [{
+ assertion = cfg.config != null;
+ message = "You must provide services.haproxy.config.";
+ }];
+
systemd.services.haproxy = {
description = "HAProxy";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "forking";
- PIDFile = "/var/run/haproxy.pid";
+ PIDFile = "/run/haproxy.pid";
ExecStartPre = "${pkgs.haproxy}/sbin/haproxy -c -q -f ${haproxyCfg}";
- ExecStart = "${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /var/run/haproxy.pid";
- ExecReload = "-${pkgs.bash}/bin/bash -c \"exec ${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /var/run/haproxy.pid -sf $MAINPID\"";
+ ExecStart = "${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid";
+ ExecReload = "-${pkgs.bash}/bin/bash -c \"exec ${pkgs.haproxy}/sbin/haproxy -D -f ${haproxyCfg} -p /run/haproxy.pid -sf $MAINPID\"";
};
};
diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
new file mode 100644
index 00000000000..7ee78f01d49
--- /dev/null
+++ b/nixos/modules/services/networking/i2pd.nix
@@ -0,0 +1,198 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.i2pd;
+
+ homeDir = "/var/lib/i2pd";
+
+ extip = "EXTIP=\$(${pkgs.curl}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
+
+ i2pSh = pkgs.writeScriptBin "i2pd" ''
+ #!/bin/sh
+ ${if isNull cfg.extIp then extip else ""}
+ ${pkgs.i2pd}/bin/i2p --log=1 --daemon=0 --service=0 \
+ --v6=${if cfg.enableIPv6 then "1" else "0"} \
+ --unreachable=${if cfg.unreachable then "1" else "0"} \
+ --host=${if isNull cfg.extIp then "$EXTIP" else cfg.extIp} \
+ ${if isNull cfg.port then "" else "--port=${toString cfg.port}"} \
+ --httpproxyport=${toString cfg.proxy.httpPort} \
+ --socksproxyport=${toString cfg.proxy.socksPort} \
+ --ircport=${toString cfg.irc.port} \
+ --ircdest=${cfg.irc.dest} \
+ --irckeys=${cfg.irc.keyFile} \
+ --eepport=${toString cfg.eep.port} \
+ ${if isNull cfg.sam.port then "" else "--samport=${toString cfg.sam.port}"} \
+ --eephost=${cfg.eep.host} \
+ --eepkeys=${cfg.eep.keyFile}
+ '';
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.i2pd = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enables I2Pd as a running service upon activation.
+ '';
+ };
+
+ extIp = mkOption {
+ type = with types; nullOr str;
+ default = null;
+ description = ''
+ Your external IP.
+ '';
+ };
+
+ unreachable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If the router is declared to be unreachable and needs introduction nodes.
+ '';
+ };
+
+ port = mkOption {
+ type = with types; nullOr int;
+ default = null;
+ description = ''
+ I2P listen port. If no one is given the router will pick between 9111 and 30777.
+ '';
+ };
+
+ enableIPv6 = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enables IPv6 connectivity. Disabled by default.
+ '';
+ };
+
+ http = {
+ port = mkOption {
+ type = types.int;
+ default = 7070;
+ description = ''
+ HTTP listen port.
+ '';
+ };
+ };
+
+ proxy = {
+ httpPort = mkOption {
+ type = types.int;
+ default = 4446;
+ description = ''
+ HTTP proxy listen port.
+ '';
+ };
+ socksPort = mkOption {
+ type = types.int;
+ default = 4447;
+ description = ''
+ SOCKS proxy listen port.
+ '';
+ };
+ };
+
+ irc = {
+ dest = mkOption {
+ type = types.str;
+ default = "irc.postman.i2p";
+ description = ''
+ Destination I2P tunnel endpoint address of IRC server. irc.postman.i2p by default.
+ '';
+ };
+ port = mkOption {
+ type = types.int;
+ default = 6668;
+ description = ''
+ Local IRC tunnel endoint port to listen on. 6668 by default.
+ '';
+ };
+ keyFile = mkOption {
+ type = types.str;
+ default = "privKeys.dat";
+ description = ''
+ File name containing destination keys. privKeys.dat by default.
+ '';
+ };
+ };
+
+ eep = {
+ host = mkOption {
+ type = types.str;
+ default = "127.0.0.1";
+ description = ''
+ Address to forward incoming traffic to. 127.0.0.1 by default.
+ '';
+ };
+ port = mkOption {
+ type = types.int;
+ default = 80;
+ description = ''
+ Port to forward incoming traffic to. 80 by default.
+ '';
+ };
+ keyFile = mkOption {
+ type = types.str;
+ default = "privKeys.dat";
+ description = ''
+ File name containing destination keys. privKeys.dat by default.
+ '';
+ };
+ };
+
+ sam = {
+ port = mkOption {
+ type = with types; nullOr int;
+ default = null;
+ description = ''
+ Local SAM tunnel endpoint. Usually 7656. SAM is disabled if not specified.
+ '';
+ };
+ };
+ };
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ users.extraUsers.i2pd = {
+ group = "i2pd";
+ description = "I2Pd User";
+ home = homeDir;
+ createHome = true;
+ uid = config.ids.uids.i2pd;
+ };
+
+ users.extraGroups.i2pd.gid = config.ids.gids.i2pd;
+
+ systemd.services.i2pd = {
+ description = "Minimal I2P router";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig =
+ {
+ User = "i2pd";
+ WorkingDirectory = homeDir;
+ Restart = "on-abort";
+ ExecStart = "${i2pSh}/bin/i2pd";
+ };
+ };
+ };
+}
+#
diff --git a/nixos/modules/services/networking/mailpile.nix b/nixos/modules/services/networking/mailpile.nix
new file mode 100644
index 00000000000..e164d41483c
--- /dev/null
+++ b/nixos/modules/services/networking/mailpile.nix
@@ -0,0 +1,76 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.mailpile;
+
+ hostname = cfg.hostname;
+ port = cfg.port;
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.mailpile = {
+ enable = mkOption {
+ default = false;
+ description = "
+ Whether to enable Mailpile the mail client.
+ ";
+ };
+ hostname = mkOption {
+ default = "localhost";
+ description = "Listen to this hostname or ip.";
+ };
+ port = mkOption {
+ default = "33411";
+ description = "Listen on this port.";
+ };
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf config.services.mailpile.enable {
+
+ users.extraUsers.mailpile =
+ { uid = config.ids.uids.mailpile;
+ description = "Mailpile user";
+ createHome = true;
+ home = "/var/lib/mailpile";
+ };
+
+ users.extraGroups.mailpile =
+ { gid = config.ids.gids.mailpile;
+ };
+
+ systemd.services.mailpile =
+ {
+ description = "Mailpile server.";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ User = "mailpile";
+ ExecStart = "${pkgs.mailpile}/bin/mailpile --www ${hostname}:${port} --wait";
+ # mixed - first send SIGINT to main process,
+ # then after 2min send SIGKILL to whole group if neccessary
+ KillMode = "mixed";
+ KillSignal = "SIGINT"; # like Ctrl+C - safe mailpile shutdown
+ TimeoutSec = 120; # wait 2min untill SIGKILL
+ };
+ environment.MAILPILE_HOME = "/var/lib/mailpile/.local/share/Mailpile";
+ };
+
+ environment.systemPackages = [ pkgs.mailpile ];
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/minidlna.nix b/nixos/modules/services/networking/minidlna.nix
index a519857d6a0..989ee4d91af 100644
--- a/nixos/modules/services/networking/minidlna.nix
+++ b/nixos/modules/services/networking/minidlna.nix
@@ -79,7 +79,7 @@ in
{ description = "MiniDLNA Server";
wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
+ after = [ "network.target" "local-fs.target" ];
preStart =
''
diff --git a/nixos/modules/services/networking/mstpd.nix b/nixos/modules/services/networking/mstpd.nix
new file mode 100644
index 00000000000..5d1fc4a6542
--- /dev/null
+++ b/nixos/modules/services/networking/mstpd.nix
@@ -0,0 +1,33 @@
+{ config, lib, pkgs, ... }:
+let
+ cfg = config.services.mstpd;
+in
+with lib;
+{
+ options.services.mstpd = {
+
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to enable the multiple spanning tree protocol daemon.
+ '';
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.mstpd ];
+
+ systemd.services.mstpd = {
+ description = "Multiple Spanning Tree Protocol Daemon";
+ wantedBy = [ "network.target" ];
+ unitConfig.ConditionCapability = "CAP_NET_ADMIN";
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "@${pkgs.mstpd}/bin/mstpd mstpd";
+ PIDFile = "/run/mstpd.pid";
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix
index e8d9d00cc0a..9d163e60d5e 100644
--- a/nixos/modules/services/networking/nat.nix
+++ b/nixos/modules/services/networking/nat.nix
@@ -12,6 +12,52 @@ let
dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}";
+ flushNat = ''
+ iptables -w -t nat -D PREROUTING -j nixos-nat-pre 2>/dev/null|| true
+ iptables -w -t nat -F nixos-nat-pre 2>/dev/null || true
+ iptables -w -t nat -X nixos-nat-pre 2>/dev/null || true
+ iptables -w -t nat -D POSTROUTING -j nixos-nat-post 2>/dev/null || true
+ iptables -w -t nat -F nixos-nat-post 2>/dev/null || true
+ iptables -w -t nat -X nixos-nat-post 2>/dev/null || true
+ '';
+
+ setupNat = ''
+ # Create subchain where we store rules
+ iptables -w -t nat -N nixos-nat-pre
+ iptables -w -t nat -N nixos-nat-post
+
+ # We can't match on incoming interface in POSTROUTING, so
+ # mark packets coming from the external interfaces.
+ ${concatMapStrings (iface: ''
+ iptables -w -t nat -A nixos-nat-pre \
+ -i '${iface}' -j MARK --set-mark 1
+ '') cfg.internalInterfaces}
+
+ # NAT the marked packets.
+ ${optionalString (cfg.internalInterfaces != []) ''
+ iptables -w -t nat -A nixos-nat-post -m mark --mark 1 \
+ -o ${cfg.externalInterface} ${dest}
+ ''}
+
+ # NAT packets coming from the internal IPs.
+ ${concatMapStrings (range: ''
+ iptables -w -t nat -A nixos-nat-post \
+ -s '${range}' -o ${cfg.externalInterface} ${dest}
+ '') cfg.internalIPs}
+
+ # NAT from external ports to internal ports.
+ ${concatMapStrings (fwd: ''
+ iptables -w -t nat -A nixos-nat-pre \
+ -i ${cfg.externalInterface} -p tcp \
+ --dport ${builtins.toString fwd.sourcePort} \
+ -j DNAT --to-destination ${fwd.destination}
+ '') cfg.forwardPorts}
+
+ # Append our chains to the nat tables
+ iptables -w -t nat -A PREROUTING -j nixos-nat-pre
+ iptables -w -t nat -A POSTROUTING -j nixos-nat-post
+ '';
+
in
{
@@ -75,6 +121,31 @@ in
'';
};
+ networking.nat.forwardPorts = mkOption {
+ type = types.listOf types.optionSet;
+ default = [];
+ example = [ { sourcePort = 8080; destination = "10.0.0.1:80"; } ];
+ options = {
+ sourcePort = mkOption {
+ type = types.int;
+ example = 8080;
+ description = "Source port of the external interface";
+ };
+
+ destination = mkOption {
+ type = types.str;
+ example = "10.0.0.1:80";
+ description = "Forward tcp connection to destination ip:port";
+ };
+ };
+
+ description =
+ ''
+ List of forwarded ports from the external interface to
+ internal destinations by using DNAT.
+ '';
+ };
+
};
@@ -84,49 +155,34 @@ in
environment.systemPackages = [ pkgs.iptables ];
- boot.kernelModules = [ "nf_nat_ftp" ];
-
- jobs.nat =
- { description = "Network Address Translation";
-
- startOn = "started network-interfaces";
-
- path = [ pkgs.iptables ];
-
- preStart =
- ''
- iptables -w -t nat -F PREROUTING
- iptables -w -t nat -F POSTROUTING
- iptables -w -t nat -X
-
- # We can't match on incoming interface in POSTROUTING, so
- # mark packets coming from the external interfaces.
- ${concatMapStrings (iface: ''
- iptables -w -t nat -A PREROUTING \
- -i '${iface}' -j MARK --set-mark 1
- '') cfg.internalInterfaces}
-
- # NAT the marked packets.
- ${optionalString (cfg.internalInterfaces != []) ''
- iptables -w -t nat -A POSTROUTING -m mark --mark 1 \
- -o ${cfg.externalInterface} ${dest}
- ''}
-
- # NAT packets coming from the internal IPs.
- ${concatMapStrings (range: ''
- iptables -w -t nat -A POSTROUTING \
- -s '${range}' -o ${cfg.externalInterface} ${dest}
- '') cfg.internalIPs}
-
- echo 1 > /proc/sys/net/ipv4/ip_forward
- '';
-
- postStop =
- ''
- iptables -w -t nat -F PREROUTING
- iptables -w -t nat -F POSTROUTING
- iptables -w -t nat -X
- '';
+ boot = {
+ kernelModules = [ "nf_nat_ftp" ];
+ kernel.sysctl = {
+ "net.ipv4.conf.all.forwarding" = mkOverride 99 true;
+ "net.ipv4.conf.default.forwarding" = mkOverride 99 true;
};
+ };
+
+ networking.firewall = mkIf config.networking.firewall.enable {
+ extraCommands = mkMerge [ (mkBefore flushNat) setupNat ];
+ extraStopCommands = flushNat;
+ };
+
+ systemd.services = mkIf (!config.networking.firewall.enable) { nat = {
+ description = "Network Address Translation";
+ wantedBy = [ "network.target" ];
+ after = [ "network-interfaces.target" "systemd-modules-load.service" ];
+ path = [ pkgs.iptables ];
+ unitConfig.ConditionCapability = "CAP_NET_ADMIN";
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+
+ script = flushNat + setupNat;
+
+ postStop = flushNat;
+ }; };
};
}
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index bc1c95d3fd3..f00c5d1f701 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -52,6 +52,7 @@ let
#!/bin/sh
if test "$2" = "up"; then
${config.systemd.package}/bin/systemctl start ip-up.target
+ ${config.systemd.package}/bin/systemctl start network-online.target
fi
'';
@@ -70,6 +71,13 @@ let
${coreutils}/bin/rm -f $tmp $tmp.ns
'';
+ # pre-up and pre-down hooks were added in NM 0.9.10, but we still use 0.9.0
+ dispatcherTypesSubdirMap = {
+ "basic" = "";
+ /*"pre-up" = "pre-up.d/";
+ "pre-down" = "pre-down.d/";*/
+ };
+
in {
###### interface
@@ -117,6 +125,30 @@ in {
'';
};
+ dispatcherScripts = mkOption {
+ type = types.listOf (types.submodule {
+ options = {
+ source = mkOption {
+ type = types.str;
+ description = ''
+ A script source.
+ '';
+ };
+
+ type = mkOption {
+ type = types.enum (attrNames dispatcherTypesSubdirMap);
+ default = "basic";
+ description = ''
+ Dispatcher hook type. Only basic hooks are currently available.
+ '';
+ };
+ };
+ });
+ default = [];
+ description = ''
+ A list of scripts which will be executed in response to network events.
+ '';
+ };
};
};
@@ -151,16 +183,24 @@ in {
{ source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
target = "NetworkManager/VPN/nm-pptp-service.name";
}
+ { source = "${networkmanager_l2tp}/etc/NetworkManager/VPN/nm-l2tp-service.name";
+ target = "NetworkManager/VPN/nm-l2tp-service.name";
+ }
] ++ optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
{ source = overrideNameserversScript;
target = "NetworkManager/dispatcher.d/02overridedns";
- };
+ }
+ ++ lib.imap (i: s: {
+ text = s.source;
+ target = "NetworkManager/dispatcher.d/${dispatcherTypesSubdirMap.${s.type}}03userscript${lib.fixedWidthNumber 4 i}";
+ }) cfg.dispatcherScripts;
environment.systemPackages = cfg.packages ++ [
networkmanager_openvpn
networkmanager_vpnc
networkmanager_openconnect
networkmanager_pptp
+ networkmanager_l2tp
modemmanager
];
@@ -177,8 +217,8 @@ in {
systemd.services."networkmanager-init" = {
description = "NetworkManager initialisation";
wantedBy = [ "network.target" ];
- wants = [ "NetworkManager.service" ];
- before = [ "NetworkManager.service" ];
+ wants = [ "network-manager.service" ];
+ before = [ "network-manager.service" ];
script = ''
mkdir -m 700 -p /etc/NetworkManager/system-connections
mkdir -m 755 -p ${stateDirs}
@@ -193,7 +233,7 @@ in {
};
powerManagement.resumeCommands = ''
- systemctl restart NetworkManager
+ ${config.systemd.package}/bin/systemctl restart network-manager
'';
security.polkit.extraConfig = polkitConf;
@@ -204,6 +244,7 @@ in {
networkmanager_vpnc
networkmanager_openconnect
networkmanager_pptp
+ networkmanager_l2tp
modemmanager
];
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index db8cb122871..36d9f5d2f16 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -9,17 +9,25 @@ let
stateDir = "/var/lib/nsd";
pidFile = stateDir + "/var/nsd.pid";
+ nsdPkg = pkgs.nsd.override {
+ bind8Stats = cfg.bind8Stats;
+ ipv6 = cfg.ipv6;
+ ratelimit = cfg.ratelimit.enable;
+ rootServer = cfg.rootServer;
+ zoneStats = length (collect (x: (x.zoneStats or null) != null) cfg.zones) > 0;
+ };
+
zoneFiles = pkgs.stdenv.mkDerivation {
- preferLocalBuild = true;
- name = "nsd-env";
- buildCommand = concatStringsSep "\n"
- [ "mkdir -p $out"
- (concatStrings (mapAttrsToList (zoneName: zoneOptions: ''
- cat > "$out/${zoneName}" <<_EOF_
- ${zoneOptions.data}
- _EOF_
- '') zoneConfigs))
- ];
+ preferLocalBuild = true;
+ name = "nsd-env";
+ buildCommand = concatStringsSep "\n"
+ [ "mkdir -p $out"
+ (concatStrings (mapAttrsToList (zoneName: zoneOptions: ''
+ cat > "$out/${zoneName}" <<_EOF_
+ ${zoneOptions.data}
+ _EOF_
+ '') zoneConfigs))
+ ];
};
configFile = pkgs.writeText "nsd.conf" ''
@@ -33,7 +41,6 @@ let
# the list of dynamically added zones.
zonelistfile: "${stateDir}/var/zone.list"
database: "${stateDir}/var/nsd.db"
- logfile: "${stateDir}/var/nsd.log"
pidfile: "${pidFile}"
xfrdfile: "${stateDir}/var/xfrd.state"
xfrdir: "${stateDir}/tmp"
@@ -105,21 +112,21 @@ let
zoneConfigFile = name: zone: ''
- zone:
- name: "${name}"
- zonefile: "${stateDir}/zones/${name}"
- ${maybeString "outgoing-interface: " zone.outgoingInterface}
- ${forEach " rrl-whitelist: " zone.rrlWhitelist}
+ zone:
+ name: "${name}"
+ zonefile: "${stateDir}/zones/${name}"
+ ${maybeString "zonestats: " zone.zoneStats}
+ ${maybeString "outgoing-interface: " zone.outgoingInterface}
+ ${forEach " rrl-whitelist: " zone.rrlWhitelist}
- ${forEach " allow-notify: " zone.allowNotify}
- ${forEach " request-xfr: " zone.requestXFR}
- allow-axfr-fallback: ${yesOrNo zone.allowAXFRFallback}
+ ${forEach " allow-notify: " zone.allowNotify}
+ ${forEach " request-xfr: " zone.requestXFR}
+ allow-axfr-fallback: ${yesOrNo zone.allowAXFRFallback}
- ${forEach " notify: " zone.notify}
- notify-retry: ${toString zone.notifyRetry}
- ${forEach " provide-xfr: " zone.provideXFR}
-
- '';
+ ${forEach " notify: " zone.notify}
+ notify-retry: ${toString zone.notifyRetry}
+ ${forEach " provide-xfr: " zone.provideXFR}
+ '';
zoneConfigs = zoneConfigs' {} "" { children = cfg.zones; };
@@ -130,8 +137,8 @@ let
# fork -> pattern
else zipAttrsWith (name: head) (
- mapAttrsToList (name: child: zoneConfigs' (parent // zone // { children = {}; }) name child)
- zone.children
+ mapAttrsToList (name: child: zoneConfigs' (parent // zone // { children = {}; }) name child)
+ zone.children
);
# fighting infinite recursion
@@ -145,138 +152,148 @@ let
childConfig = x: v: { options.children = { type = types.attrsOf x; visible = v; }; };
- zoneOptionsRaw = types.submodule (
- { options, ... }:
- { options = {
- children = mkOption {
- default = {};
- description = ''
- Children zones inherit all options of their parents. Attributes
- defined in a child will overwrite the ones of its parent. Only
- leaf zones will be actually served. This way it's possible to
- define maybe zones which share most attributes without
- duplicating everything. This mechanism replaces nsd's patterns
- in a save and functional way.
- '';
- };
-
- allowNotify = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "192.0.2.0/24 NOKEY" "10.0.0.1-10.0.0.5 my_tsig_key_name"
- "10.0.3.4&255.255.0.0 BLOCKED"
- ];
- description = ''
- Listed primary servers are allowed to notify this secondary server.
-
-
- either a plain IPv4/IPv6 address or range. Valid patters for ranges:
- * 10.0.0.0/24 # via subnet size
- * 10.0.0.0&255.255.255.0 # via subnet mask
- * 10.0.0.1-10.0.0.254 # via range
-
- A optional port number could be added with a '@':
- * 2001:1234::1@1234
-
-
- * will use the specified TSIG key
- * NOKEY no TSIG signature is required
- * BLOCKED notifies from non-listed or blocked IPs will be ignored
- * ]]>
- '';
- };
-
- requestXFR = mkOption {
- type = types.listOf types.str;
- default = [];
- example = [];
- description = ''
- Format: [AXFR|UDP] <ip-address> <key-name | NOKEY>
- '';
- };
-
- allowAXFRFallback = mkOption {
- type = types.bool;
- default = true;
- description = ''
- If NSD as secondary server should be allowed to AXFR if the primary
- server does not allow IXFR.
- '';
- };
-
- notify = mkOption {
- type = types.listOf types.str;
- default = [];
- example = [ "10.0.0.1@3721 my_key" "::5 NOKEY" ];
- description = ''
- This primary server will notify all given secondary servers about
- zone changes.
-
-
- a plain IPv4/IPv6 address with on optional port number (ip@port)
-
-
- * sign notifies with the specified key
- * NOKEY don't sign notifies
- ]]>
- '';
- };
-
- notifyRetry = mkOption {
- type = types.int;
- default = 5;
- description = ''
- Specifies the number of retries for failed notifies. Set this along with notify.
- '';
- };
-
- provideXFR = mkOption {
- type = types.listOf types.str;
- default = [];
- example = [ "192.0.2.0/24 NOKEY" "192.0.2.0/24 my_tsig_key_name" ];
- description = ''
- Allow these IPs and TSIG to transfer zones, addr TSIG|NOKEY|BLOCKED
- address range 192.0.2.0/24, 1.2.3.4&255.255.0.0, 3.0.2.20-3.0.2.40
- '';
- };
-
- outgoingInterface = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "2000::1@1234";
- description = ''
- This address will be used for zone-transfere requests if configured
- as a secondary server or notifications in case of a primary server.
- Supply either a plain IPv4 or IPv6 address with an optional port
- number (ip@port).
- '';
- };
-
- rrlWhitelist = mkOption {
- type = types.listOf types.str;
- default = [];
- description = ''
- Whitelists the given rrl-types.
- The RRL classification types are: nxdomain, error, referral, any,
- rrsig, wildcard, nodata, dnskey, positive, all
- '';
- };
-
- data = mkOption {
- type = types.str;
- default = "";
- example = "";
- description = ''
- The actual zone data. This is the content of your zone file.
- Use imports or pkgs.lib.readFile if you don't want this data in your config file.
- '';
- };
-
+ zoneOptionsRaw = types.submodule {
+ options = {
+ children = mkOption {
+ default = {};
+ description = ''
+ Children zones inherit all options of their parents. Attributes
+ defined in a child will overwrite the ones of its parent. Only
+ leaf zones will be actually served. This way it's possible to
+ define maybe zones which share most attributes without
+ duplicating everything. This mechanism replaces nsd's patterns
+ in a save and functional way.
+ '';
};
- }
- );
+
+ allowNotify = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "192.0.2.0/24 NOKEY" "10.0.0.1-10.0.0.5 my_tsig_key_name"
+ "10.0.3.4&255.255.0.0 BLOCKED"
+ ];
+ description = ''
+ Listed primary servers are allowed to notify this secondary server.
+
+
+ either a plain IPv4/IPv6 address or range. Valid patters for ranges:
+ * 10.0.0.0/24 # via subnet size
+ * 10.0.0.0&255.255.255.0 # via subnet mask
+ * 10.0.0.1-10.0.0.254 # via range
+
+ A optional port number could be added with a '@':
+ * 2001:1234::1@1234
+
+
+ * will use the specified TSIG key
+ * NOKEY no TSIG signature is required
+ * BLOCKED notifies from non-listed or blocked IPs will be ignored
+ * ]]>
+ '';
+ };
+
+ requestXFR = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [];
+ description = ''
+ Format: [AXFR|UDP] <ip-address> <key-name | NOKEY>
+ '';
+ };
+
+ allowAXFRFallback = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ If NSD as secondary server should be allowed to AXFR if the primary
+ server does not allow IXFR.
+ '';
+ };
+
+ notify = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "10.0.0.1@3721 my_key" "::5 NOKEY" ];
+ description = ''
+ This primary server will notify all given secondary servers about
+ zone changes.
+
+
+ a plain IPv4/IPv6 address with on optional port number (ip@port)
+
+
+ * sign notifies with the specified key
+ * NOKEY don't sign notifies
+ ]]>
+ '';
+ };
+
+ notifyRetry = mkOption {
+ type = types.int;
+ default = 5;
+ description = ''
+ Specifies the number of retries for failed notifies. Set this along with notify.
+ '';
+ };
+
+ provideXFR = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "192.0.2.0/24 NOKEY" "192.0.2.0/24 my_tsig_key_name" ];
+ description = ''
+ Allow these IPs and TSIG to transfer zones, addr TSIG|NOKEY|BLOCKED
+ address range 192.0.2.0/24, 1.2.3.4&255.255.0.0, 3.0.2.20-3.0.2.40
+ '';
+ };
+
+ outgoingInterface = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "2000::1@1234";
+ description = ''
+ This address will be used for zone-transfere requests if configured
+ as a secondary server or notifications in case of a primary server.
+ Supply either a plain IPv4 or IPv6 address with an optional port
+ number (ip@port).
+ '';
+ };
+
+ rrlWhitelist = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = ''
+ Whitelists the given rrl-types.
+ The RRL classification types are: nxdomain, error, referral, any,
+ rrsig, wildcard, nodata, dnskey, positive, all
+ '';
+ };
+
+ data = mkOption {
+ type = types.str;
+ default = "";
+ example = "";
+ description = ''
+ The actual zone data. This is the content of your zone file.
+ Use imports or pkgs.lib.readFile if you don't want this data in your config file.
+ '';
+ };
+
+ zoneStats = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "%s";
+ description = ''
+ When set to something distinct to null NSD is able to collect
+ statistics per zone. All statistics of this zone(s) will be added
+ to the group specified by this given name. Use "%s" to use the zones
+ name as the group. The groups are output from nsd-control stats
+ and stats_noreset.
+ '';
+ };
+ };
+ };
in
{
@@ -291,6 +308,15 @@ in
'';
};
+ bind8Stats = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Wheter to enable BIND8 like statisics.
+ '';
+ };
+
rootServer = mkOption {
type = types.bool;
default = false;
@@ -456,191 +482,162 @@ in
};
- ratelimit = mkOption {
- type = types.submodule (
- { options, ... }:
- { options = {
-
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Enable ratelimit capabilities.
- '';
- };
-
- size = mkOption {
- type = types.int;
- default = 1000000;
- description = ''
- Size of the hashtable. More buckets use more memory but lower
- the chance of hash hash collisions.
- '';
- };
-
- ratelimit = mkOption {
- type = types.int;
- default = 200;
- description = ''
- Max qps allowed from any query source.
- 0 means unlimited. With an verbosity of 2 blocked and
- unblocked subnets will be logged.
- '';
- };
-
- whitelistRatelimit = mkOption {
- type = types.int;
- default = 2000;
- description = ''
- Max qps allowed from whitelisted sources.
- 0 means unlimited. Set the rrl-whitelist option for specific
- queries to apply this limit instead of the default to them.
- '';
- };
-
- slip = mkOption {
- type = types.nullOr types.int;
- default = null;
- description = ''
- Number of packets that get discarded before replying a SLIP response.
- 0 disables SLIP responses. 1 will make every response a SLIP response.
- '';
- };
-
- ipv4PrefixLength = mkOption {
- type = types.nullOr types.int;
- default = null;
- description = ''
- IPv4 prefix length. Addresses are grouped by netblock.
- '';
- };
-
- ipv6PrefixLength = mkOption {
- type = types.nullOr types.int;
- default = null;
- description = ''
- IPv6 prefix length. Addresses are grouped by netblock.
- '';
- };
-
- };
- });
- default = {
+ ratelimit = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable ratelimit capabilities.
+ '';
+ };
+
+ size = mkOption {
+ type = types.int;
+ default = 1000000;
+ description = ''
+ Size of the hashtable. More buckets use more memory but lower
+ the chance of hash hash collisions.
+ '';
+ };
+
+ ratelimit = mkOption {
+ type = types.int;
+ default = 200;
+ description = ''
+ Max qps allowed from any query source.
+ 0 means unlimited. With an verbosity of 2 blocked and
+ unblocked subnets will be logged.
+ '';
+ };
+
+ whitelistRatelimit = mkOption {
+ type = types.int;
+ default = 2000;
+ description = ''
+ Max qps allowed from whitelisted sources.
+ 0 means unlimited. Set the rrl-whitelist option for specific
+ queries to apply this limit instead of the default to them.
+ '';
+ };
+
+ slip = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Number of packets that get discarded before replying a SLIP response.
+ 0 disables SLIP responses. 1 will make every response a SLIP response.
+ '';
+ };
+
+ ipv4PrefixLength = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ IPv4 prefix length. Addresses are grouped by netblock.
+ '';
+ };
+
+ ipv6PrefixLength = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ IPv6 prefix length. Addresses are grouped by netblock.
+ '';
};
- example = {};
- description = ''
- '';
};
- remoteControl = mkOption {
- type = types.submodule (
- { config, options, ... }:
- { options = {
-
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Wheter to enable remote control via nsd-control(8).
- '';
- };
-
- interfaces = mkOption {
- type = types.listOf types.str;
- default = [ "127.0.0.1" "::1" ];
- description = ''
- Which interfaces NSD should bind to for remote control.
- '';
- };
-
- port = mkOption {
- type = types.int;
- default = 8952;
- description = ''
- Port number for remote control operations (uses TLS over TCP).
- '';
- };
-
- serverKeyFile = mkOption {
- type = types.path;
- default = "/etc/nsd/nsd_server.key";
- description = ''
- Path to the server private key, which is used by the server
- but not by nsd-control. This file is generated by nsd-control-setup.
- '';
- };
-
- serverCertFile = mkOption {
- type = types.path;
- default = "/etc/nsd/nsd_server.pem";
- description = ''
- Path to the server self signed certificate, which is used by the server
- but and by nsd-control. This file is generated by nsd-control-setup.
- '';
- };
-
- controlKeyFile = mkOption {
- type = types.path;
- default = "/etc/nsd/nsd_control.key";
- description = ''
- Path to the client private key, which is used by nsd-control
- but not by the server. This file is generated by nsd-control-setup.
- '';
- };
-
- controlCertFile = mkOption {
- type = types.path;
- default = "/etc/nsd/nsd_control.pem";
- description = ''
- Path to the client certificate signed with the server certificate.
- This file is used by nsd-control and generated by nsd-control-setup.
- '';
- };
-
- };
-
- });
- default = {
+ remoteControl = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Wheter to enable remote control via nsd-control(8).
+ '';
+ };
+
+ interfaces = mkOption {
+ type = types.listOf types.str;
+ default = [ "127.0.0.1" "::1" ];
+ description = ''
+ Which interfaces NSD should bind to for remote control.
+ '';
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 8952;
+ description = ''
+ Port number for remote control operations (uses TLS over TCP).
+ '';
+ };
+
+ serverKeyFile = mkOption {
+ type = types.path;
+ default = "/etc/nsd/nsd_server.key";
+ description = ''
+ Path to the server private key, which is used by the server
+ but not by nsd-control. This file is generated by nsd-control-setup.
+ '';
+ };
+
+ serverCertFile = mkOption {
+ type = types.path;
+ default = "/etc/nsd/nsd_server.pem";
+ description = ''
+ Path to the server self signed certificate, which is used by the server
+ but and by nsd-control. This file is generated by nsd-control-setup.
+ '';
+ };
+
+ controlKeyFile = mkOption {
+ type = types.path;
+ default = "/etc/nsd/nsd_control.key";
+ description = ''
+ Path to the client private key, which is used by nsd-control
+ but not by the server. This file is generated by nsd-control-setup.
+ '';
+ };
+
+ controlCertFile = mkOption {
+ type = types.path;
+ default = "/etc/nsd/nsd_control.pem";
+ description = ''
+ Path to the client certificate signed with the server certificate.
+ This file is used by nsd-control and generated by nsd-control-setup.
+ '';
};
- example = {};
- description = ''
- '';
};
keys = mkOption {
- type = types.attrsOf (types.submodule (
- { options, ... }:
- { options = {
-
- algorithm = mkOption {
- type = types.str;
- default = "hmac-sha256";
- description = ''
- Authentication algorithm for this key.
- '';
- };
-
- keyFile = mkOption {
- type = types.path;
- description = ''
- Path to the file which contains the actual base64 encoded
- key. The key will be copied into "${stateDir}/private" before
- NSD starts. The copied file is only accessibly by the NSD
- user.
- '';
- };
-
+ type = types.attrsOf (types.submodule {
+ options = {
+ algorithm = mkOption {
+ type = types.str;
+ default = "hmac-sha256";
+ description = ''
+ Authentication algorithm for this key.
+ '';
};
- }));
- default = {
- };
+
+ keyFile = mkOption {
+ type = types.path;
+ description = ''
+ Path to the file which contains the actual base64 encoded
+ key. The key will be copied into "${stateDir}/private" before
+ NSD starts. The copied file is only accessibly by the NSD
+ user.
+ '';
+ };
+ };
+ });
+ default = {};
example = {
- "tsig.example.org" = {
- algorithm = "hmac-md5";
- secret = "aaaaaabbbbbbccccccdddddd";
- };
+ "tsig.example.org" = {
+ algorithm = "hmac-md5";
+ secret = "aaaaaabbbbbbccccccdddddd";
+ };
};
description = ''
Define your TSIG keys here.
@@ -651,32 +648,32 @@ in
type = types.attrsOf zoneOptions;
default = {};
example = {
- "serverGroup1" = {
- provideXFR = [ "10.1.2.3 NOKEY" ];
- children = {
- "example.com." = {
- data = ''
- $ORIGIN example.com.
- $TTL 86400
- @ IN SOA a.ns.example.com. admin.example.com. (
- ...
- '';
- };
- "example.org." = {
- data = ''
- $ORIGIN example.org.
- $TTL 86400
- @ IN SOA a.ns.example.com. admin.example.com. (
- ...
- '';
- };
- };
+ "serverGroup1" = {
+ provideXFR = [ "10.1.2.3 NOKEY" ];
+ children = {
+ "example.com." = {
+ data = ''
+ $ORIGIN example.com.
+ $TTL 86400
+ @ IN SOA a.ns.example.com. admin.example.com. (
+ ...
+ '';
+ };
+ "example.org." = {
+ data = ''
+ $ORIGIN example.org.
+ $TTL 86400
+ @ IN SOA a.ns.example.com. admin.example.com. (
+ ...
+ '';
+ };
};
+ };
- "example.net." = {
- provideXFR = [ "10.3.2.1 NOKEY" ];
- data = ''...'';
- };
+ "example.net." = {
+ provideXFR = [ "10.3.2.1 NOKEY" ];
+ data = ''...'';
+ };
};
description = ''
Define your zones here. Zones can cascade other zones and therefore
@@ -693,25 +690,18 @@ in
config = mkIf cfg.enable {
- # this is not working :(
- nixpkgs.config.nsd = {
- ipv6 = cfg.ipv6;
- ratelimit = cfg.ratelimit.enable;
- rootServer = cfg.rootServer;
- };
-
users.extraGroups = singleton {
- name = username;
- gid = config.ids.gids.nsd;
+ name = username;
+ gid = config.ids.gids.nsd;
};
users.extraUsers = singleton {
- name = username;
- description = "NSD service user";
- home = stateDir;
- createHome = true;
- uid = config.ids.uids.nsd;
- group = username;
+ name = username;
+ description = "NSD service user";
+ home = stateDir;
+ createHome = true;
+ uid = config.ids.uids.nsd;
+ group = username;
};
systemd.services.nsd = {
@@ -720,10 +710,9 @@ in
after = [ "network.target" ];
serviceConfig = {
- Type = "forking";
PIDFile = pidFile;
Restart = "always";
- ExecStart = "${pkgs.nsd}/sbin/nsd -c ${configFile}";
+ ExecStart = "${nsdPkg}/sbin/nsd -d -c ${configFile}";
};
preStart = ''
diff --git a/nixos/modules/services/networking/ntpd.nix b/nixos/modules/services/networking/ntpd.nix
index 2f638904406..a9183577d0a 100644
--- a/nixos/modules/services/networking/ntpd.nix
+++ b/nixos/modules/services/networking/ntpd.nix
@@ -11,19 +11,15 @@ let
ntpUser = "ntp";
configFile = pkgs.writeText "ntp.conf" ''
- # Keep the drift file in ${stateDir}/ntp.drift. However, since we
- # chroot to ${stateDir}, we have to specify it as /ntp.drift.
- driftfile /ntp.drift
+ driftfile ${stateDir}/ntp.drift
- restrict default kod nomodify notrap nopeer noquery
- restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
restrict -6 ::1
${toString (map (server: "server " + server + " iburst\n") config.services.ntp.servers)}
'';
- ntpFlags = "-c ${configFile} -u ${ntpUser}:nogroup -i ${stateDir}";
+ ntpFlags = "-c ${configFile} -u ${ntpUser}:nogroup";
in
@@ -45,9 +41,10 @@ in
servers = mkOption {
default = [
- "0.pool.ntp.org"
- "1.pool.ntp.org"
- "2.pool.ntp.org"
+ "0.nixos.pool.ntp.org"
+ "1.nixos.pool.ntp.org"
+ "2.nixos.pool.ntp.org"
+ "3.nixos.pool.ntp.org"
];
description = ''
The set of NTP servers from which to synchronise.
@@ -63,7 +60,7 @@ in
config = mkIf config.services.ntp.enable {
- # Make tools such as ntpq available in the system path
+ # Make tools such as ntpq available in the system path.
environment.systemPackages = [ pkgs.ntp ];
users.extraUsers = singleton
@@ -73,13 +70,10 @@ in
home = stateDir;
};
- jobs.ntpd =
+ systemd.services.ntpd =
{ description = "NTP Daemon";
- wantedBy = [ "ip-up.target" ];
- partOf = [ "ip-up.target" ];
-
- path = [ ntp ];
+ wantedBy = [ "multi-user.target" ];
preStart =
''
@@ -87,7 +81,10 @@ in
chown ${ntpUser} ${stateDir}
'';
- exec = "ntpd -g -n ${ntpFlags}";
+ serviceConfig = {
+ ExecStart = "@${ntp}/bin/ntpd ntpd -g ${ntpFlags}";
+ Type = "forking";
+ };
};
};
diff --git a/nixos/modules/services/networking/nylon.nix b/nixos/modules/services/networking/nylon.nix
new file mode 100644
index 00000000000..da6487dbd49
--- /dev/null
+++ b/nixos/modules/services/networking/nylon.nix
@@ -0,0 +1,139 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.nylon;
+
+ homeDir = "/var/lib/nylon";
+
+ configFile = pkgs.writeText "nylon.conf" ''
+ [General]
+ No-Simultaneous-Conn=${toString cfg.nrConnections}
+ Log=${if cfg.logging then "1" else "0"}
+ Verbose=${if cfg.verbosity then "1" else "0"}
+
+ [Server]
+ Binding-Interface=${cfg.acceptInterface}
+ Connecting-Interface=${cfg.bindInterface}
+ Port=${toString cfg.port}
+ Allow-IP=${concatStringsSep " " cfg.allowedIPRanges}
+ Deny-IP=${concatStringsSep " " cfg.deniedIPRanges}
+ '';
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.nylon = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enables nylon as a running service upon activation.
+ '';
+ };
+
+ nrConnections = mkOption {
+ type = types.int;
+ default = 10;
+ description = ''
+ The number of allowed simultaneous connections to the daemon, default 10.
+ '';
+ };
+
+ logging = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable logging, default is no logging.
+ '';
+ };
+
+ verbosity = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable verbose output, default is to not be verbose.
+ '';
+ };
+
+ acceptInterface = mkOption {
+ type = types.string;
+ default = "lo";
+ description = ''
+ Tell nylon which interface to listen for client requests on, default is "lo".
+ '';
+ };
+
+ bindInterface = mkOption {
+ type = types.string;
+ default = "enp3s0f0";
+ description = ''
+ Tell nylon which interface to use as an uplink, default is "enp3s0f0".
+ '';
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 1080;
+ description = ''
+ What port to listen for client requests, default is 1080.
+ '';
+ };
+
+ allowedIPRanges = mkOption {
+ type = with types; listOf string;
+ default = [ "192.168.0.0/16" "127.0.0.1/8" "172.16.0.1/12" "10.0.0.0/8" ];
+ description = ''
+ Allowed client IP ranges are evaluated first, defaults to ARIN IPv4 private ranges:
+ [ "192.168.0.0/16" "127.0.0.0/8" "172.16.0.0/12" "10.0.0.0/8" ]
+ '';
+ };
+
+ deniedIPRanges = mkOption {
+ type = with types; listOf string;
+ default = [ "0.0.0.0/0" ];
+ description = ''
+ Denied client IP ranges, these gets evaluated after the allowed IP ranges, defaults to all IPv4 addresses:
+ [ "0.0.0.0/0" ]
+ To block all other access than the allowed.
+ '';
+ };
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ users.extraUsers.nylon= {
+ group = "nylon";
+ description = "Nylon SOCKS Proxy";
+ home = homeDir;
+ createHome = true;
+ uid = config.ids.uids.nylon;
+ };
+
+ users.extraGroups.nylon.gid = config.ids.gids.nylon;
+
+ systemd.services.nylon = {
+ description = "Nylon, a lightweight SOCKS proxy server";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig =
+ {
+ User = "nylon";
+ Group = "nylon";
+ WorkingDirectory = homeDir;
+ ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile}";
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/openntpd.nix b/nixos/modules/services/networking/openntpd.nix
new file mode 100644
index 00000000000..e53fc574fbe
--- /dev/null
+++ b/nixos/modules/services/networking/openntpd.nix
@@ -0,0 +1,72 @@
+{ pkgs, lib, config, options, ... }:
+
+with lib;
+
+let
+ cfg = config.services.openntpd;
+
+ package = pkgs.openntpd_nixos;
+
+ cfgFile = pkgs.writeText "openntpd.conf" ''
+ ${concatStringsSep "\n" (map (s: "server ${s}") cfg.servers)}
+ ${cfg.extraConfig}
+ '';
+in
+{
+ ###### interface
+
+ options.services.openntpd = {
+ enable = mkEnableOption "OpenNTP time synchronization server";
+
+ servers = mkOption {
+ default = config.services.ntp.servers;
+ type = types.listOf types.str;
+ inherit (options.services.ntp.servers) description;
+ };
+
+ extraConfig = mkOption {
+ type = with types; lines;
+ default = "";
+ example = ''
+ listen on 127.0.0.1
+ listen on ::1
+ '';
+ description = ''
+ Additional text appended to openntpd.conf .
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = with types; string;
+ default = "";
+ example = "-s";
+ description = ''
+ Extra options used when launching openntpd.
+ '';
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ services.ntp.enable = mkForce false;
+
+ # Add ntpctl to the environment for status checking
+ environment.systemPackages = [ package ];
+
+ users.extraUsers = singleton {
+ name = "ntp";
+ uid = config.ids.uids.ntp;
+ description = "OpenNTP daemon user";
+ home = "/var/empty";
+ };
+
+ systemd.services.openntpd = {
+ description = "OpenNTP Server";
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "network-online.target" ];
+ after = [ "dnsmasq.service" "bind.service" "network-online.target" ];
+ serviceConfig.ExecStart = "${package}/sbin/ntpd -d -f ${cfgFile} ${cfg.extraOptions}";
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/polipo.nix b/nixos/modules/services/networking/polipo.nix
index 05ded84625d..51179d9120f 100644
--- a/nixos/modules/services/networking/polipo.nix
+++ b/nixos/modules/services/networking/polipo.nix
@@ -103,12 +103,8 @@ in
description = "caching web proxy";
after = [ "network.target" "nss-lookup.target" ];
wantedBy = [ "multi-user.target"];
- preStart = ''
- ${pkgs.coreutils}/bin/chown polipo:polipo /var/cache/polipo -R
- '';
serviceConfig = {
ExecStart = "${pkgs.polipo}/bin/polipo -c ${polipoConfig}";
- ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
User = "polipo";
};
};
diff --git a/nixos/modules/services/networking/privoxy.nix b/nixos/modules/services/networking/privoxy.nix
index 950112b2dab..94beb78ef5a 100644
--- a/nixos/modules/services/networking/privoxy.nix
+++ b/nixos/modules/services/networking/privoxy.nix
@@ -6,19 +6,18 @@ let
inherit (pkgs) privoxy;
- stateDir = "/var/spool/privoxy";
-
privoxyUser = "privoxy";
- privoxyFlags = "--no-daemon --user ${privoxyUser} ${privoxyCfg}";
+ cfg = config.services.privoxy;
- privoxyCfg = pkgs.writeText "privoxy.conf" ''
- listen-address ${config.services.privoxy.listenAddress}
- logdir ${config.services.privoxy.logDir}
- confdir ${privoxy}/etc
- filterfile default.filter
-
- ${config.services.privoxy.extraConfig}
+ confFile = pkgs.writeText "privoxy.conf" ''
+ user-manual ${privoxy}/share/doc/privoxy/user-manual
+ confdir ${privoxy}/etc/
+ listen-address ${cfg.listenAddress}
+ enable-edit-actions ${if (cfg.enableEditActions == true) then "1" else "0"}
+ ${concatMapStrings (f: "actionsfile ${f}\n") cfg.actionsFiles}
+ ${concatMapStrings (f: "filterfile ${f}\n") cfg.filterFiles}
+ ${cfg.extraConfig}
'';
in
@@ -32,27 +31,51 @@ in
services.privoxy = {
enable = mkOption {
+ type = types.bool;
default = false;
description = ''
- Whether to run the machine as a HTTP proxy server.
+ Whether to enable the Privoxy non-caching filtering proxy.
'';
};
listenAddress = mkOption {
+ type = types.str;
default = "127.0.0.1:8118";
description = ''
Address the proxy server is listening to.
'';
};
- logDir = mkOption {
- default = "/var/log/privoxy" ;
+ actionsFiles = mkOption {
+ type = types.listOf types.str;
+ example = [ "match-all.action" "default.action" "/etc/privoxy/user.action" ];
+ default = [ "match-all.action" "default.action" ];
description = ''
- Location for privoxy log files.
+ List of paths to Privoxy action files.
+ These paths may either be absolute or relative to the privoxy configuration directory.
+ '';
+ };
+
+ filterFiles = mkOption {
+ type = types.listOf types.str;
+ example = [ "default.filter" "/etc/privoxy/user.filter" ];
+ default = [ "default.filter" ];
+ description = ''
+ List of paths to Privoxy filter files.
+ These paths may either be absolute or relative to the privoxy configuration directory.
+ '';
+ };
+
+ enableEditActions = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether or not the web-based actions file editor may be used.
'';
};
extraConfig = mkOption {
+ type = types.lines;
default = "" ;
description = ''
Extra configuration. Contents will be added verbatim to the configuration file.
@@ -62,33 +85,22 @@ in
};
-
###### implementation
- config = mkIf config.services.privoxy.enable {
+ config = mkIf cfg.enable {
- environment.systemPackages = [ privoxy ];
-
users.extraUsers = singleton
{ name = privoxyUser;
uid = config.ids.uids.privoxy;
description = "Privoxy daemon user";
- home = stateDir;
};
- jobs.privoxy =
- { name = "privoxy";
-
- startOn = "startup";
-
- preStart =
- ''
- mkdir -m 0755 -p ${stateDir}
- chown ${privoxyUser} ${stateDir}
- '';
-
- exec = "${privoxy}/sbin/privoxy ${privoxyFlags}";
- };
+ systemd.services.privoxy = {
+ description = "Filtering web proxy";
+ after = [ "network.target" "nss-lookup.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig.ExecStart = "${privoxy}/sbin/privoxy --no-daemon --user ${privoxyUser} ${confFile}";
+ };
};
diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix
new file mode 100644
index 00000000000..f82f8bfddbb
--- /dev/null
+++ b/nixos/modules/services/networking/prosody.nix
@@ -0,0 +1,280 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.prosody;
+
+ sslOpts = { ... }: {
+
+ options = {
+
+ # TODO: require attribute
+ key = mkOption {
+ type = types.str;
+ description = "Path to the key file";
+ };
+
+ # TODO: require attribute
+ cert = mkOption {
+ type = types.str;
+ description = "Path to the certificate file";
+ };
+ };
+ };
+
+ moduleOpts = {
+
+ roster = mkOption {
+ default = true;
+ description = "Allow users to have a roster";
+ };
+
+ saslauth = mkOption {
+ default = true;
+ description = "Authentication for clients and servers. Recommended if you want to log in.";
+ };
+
+ tls = mkOption {
+ default = true;
+ description = "Add support for secure TLS on c2s/s2s connections";
+ };
+
+ dialback = mkOption {
+ default = true;
+ description = "s2s dialback support";
+ };
+
+ disco = mkOption {
+ default = true;
+ description = "Service discovery";
+ };
+
+ legacyauth = mkOption {
+ default = true;
+ description = "Legacy authentication. Only used by some old clients and bots";
+ };
+
+ version = mkOption {
+ default = true;
+ description = "Replies to server version requests";
+ };
+
+ uptime = mkOption {
+ default = true;
+ description = "Report how long server has been running";
+ };
+
+ time = mkOption {
+ default = true;
+ description = "Let others know the time here on this server";
+ };
+
+ ping = mkOption {
+ default = true;
+ description = "Replies to XMPP pings with pongs";
+ };
+
+ console = mkOption {
+ default = false;
+ description = "telnet to port 5582";
+ };
+
+ bosh = mkOption {
+ default = false;
+ description = "Enable BOSH clients, aka 'Jabber over HTTP'";
+ };
+
+ httpserver = mkOption {
+ default = false;
+ description = "Serve static files from a directory over HTTP";
+ };
+
+ websocket = mkOption {
+ default = false;
+ description = "Enable WebSocket support";
+ };
+
+ };
+
+ createSSLOptsStr = o:
+ if o ? key && o ? cert then
+ ''ssl = { key = "${o.key}"; certificate = "${o.cert}"; };''
+ else "";
+
+ vHostOpts = { ... }: {
+
+ options = {
+
+ # TODO: require attribute
+ domain = mkOption {
+ type = types.str;
+ description = "Domain name";
+ };
+
+ enabled = mkOption {
+ default = false;
+ description = "Whether to enable the virtual host";
+ };
+
+ ssl = mkOption {
+ description = "Paths to SSL files";
+ default = null;
+ options = [ sslOpts ];
+ };
+
+ extraConfig = mkOption {
+ default = '''';
+ description = "Additional virtual host specific configuration";
+ };
+
+ };
+
+ };
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.prosody = {
+
+ enable = mkOption {
+ default = false;
+ description = "Whether to enable the prosody server";
+ };
+
+ allowRegistration = mkOption {
+ default = false;
+ description = "Allow account creation";
+ };
+
+ modules = moduleOpts;
+
+ extraModules = mkOption {
+ description = "Enable custom modules";
+ default = [];
+ };
+
+ virtualHosts = mkOption {
+
+ description = "Define the virtual hosts";
+
+ type = types.loaOf types.optionSet;
+
+ example = {
+ myhost = {
+ domain = "my-xmpp-example-host.org";
+ enabled = true;
+ };
+ };
+
+ default = {
+ localhost = {
+ domain = "localhost";
+ enabled = true;
+ };
+ };
+
+ options = [ vHostOpts ];
+ };
+
+ ssl = mkOption {
+ description = "Paths to SSL files";
+ default = null;
+ options = [ sslOpts ];
+ };
+
+ admins = mkOption {
+ description = "List of administrators of the current host";
+ example = [ "admin1@example.com" "admin2@example.com" ];
+ default = [];
+ };
+
+ extraConfig = mkOption {
+ default = '''';
+ description = "Additional prosody configuration";
+ };
+
+ };
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ environment.systemPackages = [ pkgs.prosody ];
+
+ environment.etc."prosody/prosody.cfg.lua".text = ''
+
+ pidfile = "/var/lib/prosody/prosody.pid"
+
+
+ log = "*syslog"
+
+ data_path = "/var/lib/prosody"
+
+ allow_registration = ${ if cfg.allowRegistration then "true" else "false" };
+
+ ${ optionalString cfg.modules.console "console_enabled = true;" }
+
+ ${ optionalString (cfg.ssl != null) (createSSLOptsStr cfg.ssl) }
+
+ admins = { ${lib.concatStringsSep ", " (map (n: "\"${n}\"") cfg.admins) } };
+
+ modules_enabled = {
+
+ ${ lib.concatStringsSep "\n\ \ " (lib.mapAttrsToList
+ (name: val: optionalString val ''"${name}";'')
+ cfg.modules) }
+
+ ${ optionalString cfg.allowRegistration "\"register\"\;" }
+
+ ${ lib.concatStringsSep "\n" (map (x: "\"${x}\";") cfg.extraModules)}
+
+ "posix";
+ };
+
+ ${ cfg.extraConfig }
+
+ ${ lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: ''
+ VirtualHost "${v.domain}"
+ enabled = ${if v.enabled then "true" else "false"};
+ ${ optionalString (v.ssl != null) (createSSLOptsStr v.ssl) }
+ ${ v.extraConfig }
+ '') cfg.virtualHosts) }
+ '';
+
+ users.extraUsers.prosody = {
+ uid = config.ids.uids.prosody;
+ description = "Prosody user";
+ createHome = true;
+ group = "prosody";
+ home = "/var/lib/prosody";
+ };
+
+ users.extraGroups.prosody = {
+ gid = config.ids.gids.prosody;
+ };
+
+ systemd.services.prosody = {
+
+ description = "Prosody XMPP server";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ User = "prosody";
+ PIDFile = "/var/lib/prosody/prosody.pid";
+ ExecStart = "${pkgs.prosody}/bin/prosodyctl start";
+ };
+
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index 749e5dcebb6..579d62884c7 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -74,21 +74,23 @@ in
gid = config.ids.gids.quassel;
}];
- jobs.quassel =
+ systemd.services.quassel =
{ description = "Quassel IRC client daemon";
- startOn = "ip-up";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
preStart = ''
- mkdir -p ${cfg.dataDir}
- chown ${user} ${cfg.dataDir}
+ mkdir -p ${cfg.dataDir}
+ chown ${user} ${cfg.dataDir}
'';
- exec = ''
- ${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${user} \
- -c '${quassel}/bin/quasselcore --listen=${cfg.interface}\
- --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}'
- '';
+ serviceConfig =
+ {
+ ExecStart = "${quassel}/bin/quasselcore --listen=${cfg.interface} --port=${toString cfg.portNumber} --configdir=${cfg.dataDir}";
+ User = user;
+ PermissionsStartOnly = true;
+ };
};
};
diff --git a/nixos/modules/services/networking/rdnssd.nix b/nixos/modules/services/networking/rdnssd.nix
index 4c1891816e3..95833d31e99 100644
--- a/nixos/modules/services/networking/rdnssd.nix
+++ b/nixos/modules/services/networking/rdnssd.nix
@@ -4,7 +4,12 @@
{ config, lib, pkgs, ... }:
with lib;
-
+let
+ mergeHook = pkgs.writeScript "rdnssd-merge-hook" ''
+ #! ${pkgs.stdenv.shell} -e
+ ${pkgs.openresolv}/bin/resolvconf -u
+ '';
+in
{
###### interface
@@ -30,18 +35,39 @@ with lib;
config = mkIf config.services.rdnssd.enable {
- jobs.rdnssd =
- { description = "RDNSS daemon";
+ systemd.services.rdnssd = {
+ description = "RDNSS daemon";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
- # Start before the network interfaces are brought up so that
- # the daemon receives RDNSS advertisements from the kernel.
- startOn = "starting network-interfaces";
+ preStart = ''
+ # Create the proper run directory
+ mkdir -p /run/rdnssd
+ touch /run/rdnssd/resolv.conf
+ chown -R rdnssd /run/rdnssd
- # !!! Should write to /var/run/rdnssd/resolv.conf and run the daemon under another uid.
- exec = "${pkgs.ndisc6}/sbin/rdnssd --resolv-file /etc/resolv.conf -u root";
+ # Link the resolvconf interfaces to rdnssd
+ rm -f /run/resolvconf/interfaces/rdnssd
+ ln -s /run/rdnssd/resolv.conf /run/resolvconf/interfaces/rdnssd
+ ${mergeHook}
+ '';
- daemonType = "fork";
+ postStop = ''
+ rm -f /run/resolvconf/interfaces/rdnssd
+ ${mergeHook}
+ '';
+
+ serviceConfig = {
+ ExecStart = "@${pkgs.ndisc6}/bin/rdnssd rdnssd -p /run/rdnssd/rdnssd.pid -r /run/rdnssd/resolv.conf -u rdnssd -H ${mergeHook}";
+ Type = "forking";
+ PIDFile = "/run/rdnssd/rdnssd.pid";
};
+ };
+
+ users.extraUsers.rdnssd = {
+ description = "RDNSSD Daemon User";
+ uid = config.ids.uids.rdnssd;
+ };
};
diff --git a/nixos/modules/services/networking/sabnzbd.nix b/nixos/modules/services/networking/sabnzbd.nix
index 83db0841b34..77bf64b80d0 100644
--- a/nixos/modules/services/networking/sabnzbd.nix
+++ b/nixos/modules/services/networking/sabnzbd.nix
@@ -39,13 +39,14 @@ in
}
];
- jobs.sabnzbd =
+ systemd.services.sabnzbd =
{ description = "sabnzbd server";
-
- startOn = "started network-interfaces";
- stopOn = "stopping network-interfaces";
-
- exec = "${sabnzbd}/bin/sabnzbd -d -f ${cfg.configFile}";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${sabnzbd}/bin/sabnzbd -d -f ${cfg.configFile}";
+ };
};
};
diff --git a/nixos/modules/services/networking/seeks.nix b/nixos/modules/services/networking/seeks.nix
new file mode 100644
index 00000000000..155ecbb98ef
--- /dev/null
+++ b/nixos/modules/services/networking/seeks.nix
@@ -0,0 +1,75 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.seeks;
+
+ confDir = cfg.confDir;
+
+ seeks = pkgs.seeks.override { seeks_confDir = confDir; };
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.seeks = {
+
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = "
+ Whether to enable the Seeks server.
+ ";
+ };
+
+ confDir = mkOption {
+ default = "";
+ type = types.str;
+ description = "
+ The Seeks server configuration. If it is not specified,
+ a default configuration is used (${seeks}/etc/seeks).
+ ";
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf config.services.seeks.enable {
+
+ users.extraUsers.seeks =
+ { uid = config.ids.uids.seeks;
+ description = "Seeks user";
+ createHome = true;
+ home = "/var/lib/seeks";
+ };
+
+ users.extraGroups.seeks =
+ { gid = config.ids.gids.seeks;
+ };
+
+ systemd.services.seeks =
+ {
+ description = "Seeks server, the p2p search engine.";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ User = "seeks";
+ ExecStart = "${seeks}/bin/seeks";
+ };
+ };
+
+ environment.systemPackages = [ seeks ];
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index e4b29a0b909..b2740bd33b7 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -9,19 +9,13 @@ let
nssModulesPath = config.system.nssModules.path;
- permitRootLoginCheck = v:
- v == "yes" ||
- v == "without-password" ||
- v == "forced-commands-only" ||
- v == "no";
-
knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
- knownHostsFile = pkgs.writeText "ssh_known_hosts" (
- flip concatMapStrings knownHosts (h: ''
- ${concatStringsSep "," h.hostNames} ${if h.publicKey != null then h.publicKey else readFile h.publicKeyFile}
- '')
- );
+ knownHostsText = flip (concatMapStringsSep "\n") knownHosts
+ (h:
+ concatStringsSep "," h.hostNames + " "
+ + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
+ );
userOptions = {
@@ -116,12 +110,9 @@ in
permitRootLogin = mkOption {
default = "without-password";
- type = types.addCheck types.str permitRootLoginCheck;
+ type = types.enum ["yes" "without-password" "forced-commands-only" "no"];
description = ''
- Whether the root user can login using ssh. Valid values are
- yes , without-password ,
- forced-commands-only or
- no .
+ Whether the root user can login using ssh.
'';
};
@@ -144,6 +135,36 @@ in
'';
};
+ listenAddresses = mkOption {
+ type = types.listOf types.optionSet;
+ default = [];
+ example = [ { addr = "192.168.3.1"; port = 22; } { addr = "0.0.0.0"; port = 64022; } ];
+ description = ''
+ List of addresses and ports to listen on (ListenAddress directive
+ in config). If port is not specified for address sshd will listen
+ on all ports specified by ports option.
+ NOTE: this will override default listening on all local addresses and port 22.
+ NOTE: setting this option won't automatically enable given ports
+ in firewall configuration.
+ '';
+ options = {
+ addr = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Host, IPv4 or IPv6 address to listen to.
+ '';
+ };
+ port = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Port to listen to.
+ '';
+ };
+ };
+ };
+
passwordAuthentication = mkOption {
type = types.bool;
default = true;
@@ -165,12 +186,14 @@ in
default =
[ { path = "/etc/ssh/ssh_host_dsa_key";
type = "dsa";
- bits = 1024;
}
{ path = "/etc/ssh/ssh_host_ecdsa_key";
type = "ecdsa";
bits = 521;
}
+ { path = "/etc/ssh/ssh_host_ed25519_key";
+ type = "ed25519";
+ }
];
description = ''
NixOS can automatically generate SSH host keys. This option
@@ -224,7 +247,10 @@ in
description = ''
The public key data for the host. You can fetch a public key
from a running SSH server with the ssh-keyscan
- command.
+ command. The public key should not include any host names, only
+ the key type and the key itself. It is allowed to add several
+ lines here, each line will be treated as type/key pair and the
+ host names will be prepended to each line.
'';
};
publicKeyFile = mkOption {
@@ -234,7 +260,9 @@ in
The path to the public key file for the host. The public
key file is read at build time and saved in the Nix store.
You can fetch a public key file from a running SSH server
- with the ssh-keyscan command.
+ with the ssh-keyscan command. The content
+ of the file should follow the same format as described for
+ the publicKey option.
'';
};
};
@@ -261,10 +289,10 @@ in
};
environment.etc = authKeysFiles ++ [
- { source = "${pkgs.openssh}/etc/ssh/moduli";
+ { source = "${cfgc.package}/etc/ssh/moduli";
target = "ssh/moduli";
}
- { source = knownHostsFile;
+ { text = knownHostsText;
target = "ssh/ssh_known_hosts";
}
];
@@ -278,7 +306,7 @@ in
stopIfChanged = false;
- path = [ pkgs.openssh pkgs.gawk ];
+ path = [ cfgc.package pkgs.gawk ];
environment.LD_LIBRARY_PATH = nssModulesPath;
@@ -288,14 +316,14 @@ in
${flip concatMapStrings cfg.hostKeys (k: ''
if ! [ -f "${k.path}" ]; then
- ssh-keygen -t "${k.type}" -b "${toString k.bits}" -f "${k.path}" -N ""
+ ssh-keygen -t "${k.type}" ${if k ? bits then "-b ${toString k.bits}" else ""} -f "${k.path}" -N ""
fi
'')}
'';
serviceConfig =
{ ExecStart =
- "${pkgs.openssh}/sbin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
+ "${cfgc.package}/sbin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
KillMode = "process";
} // (if cfg.startWhenNeeded then {
@@ -344,11 +372,17 @@ in
UsePAM yes
+ UsePrivilegeSeparation sandbox
+
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
${concatMapStrings (port: ''
Port ${toString port}
'') cfg.ports}
+ ${concatMapStrings ({ port, addr }: ''
+ ListenAddress ${addr}${if port != null then ":" + toString port else ""}
+ '') cfg.listenAddresses}
+
${optionalString cfgc.setXAuthLocation ''
XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
''}
@@ -360,7 +394,7 @@ in
''}
${optionalString cfg.allowSFTP ''
- Subsystem sftp ${pkgs.openssh}/libexec/sftp-server
+ Subsystem sftp ${cfgc.package}/libexec/sftp-server
''}
PermitRootLogin ${cfg.permitRootLogin}
@@ -383,6 +417,10 @@ in
assertion = (data.publicKey == null && data.publicKeyFile != null) ||
(data.publicKey != null && data.publicKeyFile == null);
message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
+ })
+ ++ flip map cfg.listenAddresses ({ addr, port }: {
+ assertion = addr != null;
+ message = "addr must be specified in each listenAddresses entry";
});
};
diff --git a/nixos/modules/services/networking/sslh.nix b/nixos/modules/services/networking/sslh.nix
new file mode 100644
index 00000000000..e251571dca3
--- /dev/null
+++ b/nixos/modules/services/networking/sslh.nix
@@ -0,0 +1,89 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.sslh;
+ configFile = pkgs.writeText "sslh.conf" ''
+ verbose: ${if cfg.verbose then "true" else "false"};
+ foreground: true;
+ inetd: false;
+ numeric: false;
+ transparent: false;
+ timeout: "${toString cfg.timeout}";
+ user: "nobody";
+ pidfile: "${cfg.pidfile}";
+
+ listen:
+ (
+ { host: "${cfg.host}"; port: "${toString cfg.port}"; }
+ );
+
+ ${cfg.appendConfig}
+ '';
+ defaultAppendConfig = ''
+ protocols:
+ (
+ { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; probe: "builtin"; },
+ { name: "openvpn"; host: "localhost"; port: "1194"; probe: "builtin"; },
+ { name: "xmpp"; host: "localhost"; port: "5222"; probe: "builtin"; },
+ { name: "http"; host: "localhost"; port: "80"; probe: "builtin"; },
+ { name: "ssl"; host: "localhost"; port: "443"; probe: "builtin"; },
+ { name: "anyprot"; host: "localhost"; port: "443"; probe: "builtin"; }
+ );
+ '';
+in
+{
+ options = {
+ services.sslh = {
+ enable = mkEnableOption "sslh";
+
+ verbose = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Verbose logs.";
+ };
+
+ timeout = mkOption {
+ type = types.int;
+ default = 2;
+ description = "Timeout in seconds.";
+ };
+
+ pidfile = mkOption {
+ type = types.path;
+ default = "/run/sslh.pid";
+ description = "PID file path for sslh daemon.";
+ };
+
+ host = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ description = "Listening hostname.";
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 443;
+ description = "Listening port.";
+ };
+
+ appendConfig = mkOption {
+ type = types.str;
+ default = defaultAppendConfig;
+ description = "Verbatim configuration file.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.sslh = {
+ description = "Applicative Protocol Multiplexer (e.g. share SSH and HTTPS on the same port)";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig.ExecStart = "${pkgs.sslh}/bin/sslh -F ${configFile}";
+ serviceConfig.KillMode = "process";
+ serviceConfig.PIDFile = "${cfg.pidfile}";
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/strongswan.nix b/nixos/modules/services/networking/strongswan.nix
new file mode 100644
index 00000000000..8778b0364f9
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+
+let
+
+ inherit (builtins) toFile;
+ inherit (lib) concatMapStringsSep concatStringsSep mapAttrsToList
+ mkIf mkEnableOption mkOption types;
+
+ cfg = config.services.strongswan;
+
+ ipsecSecrets = secrets: toFile "ipsec.secrets" (
+ concatMapStringsSep "\n" (f: "include ${f}") secrets
+ );
+
+ ipsecConf = {setup, connections, ca}:
+ let
+ # https://wiki.strongswan.org/projects/strongswan/wiki/IpsecConf
+ makeSections = type: sections: concatStringsSep "\n\n" (
+ mapAttrsToList (sec: attrs:
+ "${type} ${sec}\n" +
+ (concatStringsSep "\n" ( mapAttrsToList (k: v: " ${k}=${v}") attrs ))
+ ) sections
+ );
+ setupConf = makeSections "config" { inherit setup; };
+ connectionsConf = makeSections "conn" connections;
+ caConf = makeSections "ca" ca;
+
+ in
+ builtins.toFile "ipsec.conf" ''
+ ${setupConf}
+ ${connectionsConf}
+ ${caConf}
+ '';
+
+ strongswanConf = {setup, connections, ca, secrets}: toFile "strongswan.conf" ''
+ charon {
+ plugins {
+ stroke {
+ secrets_file = ${ipsecSecrets secrets}
+ }
+ }
+ }
+
+ starter {
+ config_file = ${ipsecConf { inherit setup connections ca; }}
+ }
+ '';
+
+in
+{
+ options.services.strongswan = {
+ enable = mkEnableOption "strongSwan";
+
+ secrets = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ example = [ "/run/keys/ipsec-foo.secret" ];
+ description = ''
+ A list of paths to IPSec secret files. These
+ files will be included into the main ipsec.secrets file with
+ the include directive. It is safer if these
+ paths are absolute.
+ '';
+ };
+
+ setup = mkOption {
+ type = types.attrsOf types.str;
+ default = {};
+ example = { cachecrls = "yes"; strictcrlpolicy = "yes"; };
+ description = ''
+ A set of options for the ‘config setup’ section of the
+ ipsec.conf file. Defines general
+ configuration parameters.
+ '';
+ };
+
+ connections = mkOption {
+ type = types.attrsOf (types.attrsOf types.str);
+ default = {};
+ example = {
+ "%default" = {
+ keyexchange = "ikev2";
+ keyingtries = "1";
+ };
+ roadwarrior = {
+ auto = "add";
+ leftcert = "/run/keys/moonCert.pem";
+ leftid = "@moon.strongswan.org";
+ leftsubnet = "10.1.0.0/16";
+ right = "%any";
+ };
+ };
+ description = ''
+ A set of connections and their options for the ‘conn xxx’
+ sections of the ipsec.conf file.
+ '';
+ };
+
+ ca = mkOption {
+ type = types.attrsOf (types.attrsOf types.str);
+ default = {};
+ example = {
+ strongswan = {
+ auto = "add";
+ cacert = "/run/keys/strongswanCert.pem";
+ crluri = "http://crl2.strongswan.org/strongswan.crl";
+ };
+ };
+ description = ''
+ A set of CAs (certification authorities) and their options for
+ the ‘ca xxx’ sections of the ipsec.conf
+ file.
+ '';
+ };
+ };
+
+ config = with cfg; mkIf enable {
+ systemd.services.strongswan = {
+ description = "strongSwan IPSec Service";
+ wantedBy = [ "multi-user.target" ];
+ path = with pkgs; [ kmod iproute iptables utillinux ]; # XXX Linux
+ wants = [ "keys.target" ];
+ after = [ "network.target" "keys.target" ];
+ environment = {
+ STRONGSWAN_CONF = strongswanConf { inherit setup connections ca secrets; };
+ };
+ serviceConfig = {
+ ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork";
+ };
+ };
+ };
+}
+
diff --git a/nixos/modules/services/networking/tcpcrypt.nix b/nixos/modules/services/networking/tcpcrypt.nix
index 1359006aef4..fbd581cc4b4 100644
--- a/nixos/modules/services/networking/tcpcrypt.nix
+++ b/nixos/modules/services/networking/tcpcrypt.nix
@@ -44,6 +44,8 @@ in
path = [ pkgs.iptables pkgs.tcpcrypt pkgs.procps ];
preStart = ''
+ mkdir -p /var/run/tcpcryptd
+ chown tcpcryptd /var/run/tcpcryptd
sysctl -n net.ipv4.tcp_ecn >/run/pre-tcpcrypt-ecn-state
sysctl -w net.ipv4.tcp_ecn=0
diff --git a/nixos/modules/services/networking/tftpd.nix b/nixos/modules/services/networking/tftpd.nix
index a2f7ff06ea6..9b3cc6b8ec4 100644
--- a/nixos/modules/services/networking/tftpd.nix
+++ b/nixos/modules/services/networking/tftpd.nix
@@ -9,16 +9,18 @@ with lib;
options = {
services.tftpd.enable = mkOption {
+ type = types.bool;
default = false;
description = ''
- Whether to enable the anonymous FTP user.
+ Whether to enable tftpd, a Trivial File Transfer Protocol server.
'';
};
services.tftpd.path = mkOption {
+ type = types.path;
default = "/home/tftp";
description = ''
- Where the tftp server files are stored
+ Where the tftp server files are stored.
'';
};
diff --git a/nixos/modules/services/networking/tinc.nix b/nixos/modules/services/networking/tinc.nix
new file mode 100644
index 00000000000..f9ca796ea65
--- /dev/null
+++ b/nixos/modules/services/networking/tinc.nix
@@ -0,0 +1,162 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.tinc;
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.tinc = {
+
+ networks = mkOption {
+ default = { };
+ type = types.loaOf types.optionSet;
+ description = ''
+ Defines the tinc networks which will be started.
+ Each network invokes a different daemon.
+ '';
+ options = {
+
+ extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Extra lines to add to the tinc service configuration file.
+ '';
+ };
+
+ name = mkOption {
+ default = null;
+ type = types.nullOr types.str;
+ description = ''
+ The name of the node which is used as an identifier when communicating
+ with the remote nodes in the mesh. If null then the hostname of the system
+ is used.
+ '';
+ };
+
+ debugLevel = mkOption {
+ default = 0;
+ type = types.addCheck types.int (l: l >= 0 && l <= 5);
+ description = ''
+ The amount of debugging information to add to the log. 0 means little
+ logging while 5 is the most logging. man tincd for
+ more details.
+ '';
+ };
+
+ hosts = mkOption {
+ default = { };
+ type = types.loaOf types.lines;
+ description = ''
+ The name of the host in the network as well as the configuration for that host.
+ This name should only contain alphanumerics and underscores.
+ '';
+ };
+
+ interfaceType = mkOption {
+ default = "tun";
+ type = types.addCheck types.str (n: n == "tun" || n == "tap");
+ description = ''
+ The type of virtual interface used for the network connection
+ '';
+ };
+
+ package = mkOption {
+ default = pkgs.tinc_pre;
+ description = ''
+ The package to use for the tinc daemon's binary.
+ '';
+ };
+
+ };
+ };
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf (cfg.networks != { }) {
+
+ environment.etc = fold (a: b: a // b) { }
+ (flip mapAttrsToList cfg.networks (network: data:
+ flip mapAttrs' data.hosts (host: text: nameValuePair
+ ("tinc/${network}/hosts/${host}")
+ ({ mode = "0444"; inherit text; })
+ ) // {
+ "tinc/${network}/tinc.conf" = {
+ mode = "0444";
+ text = ''
+ Name = ${if data.name == null then "$HOST" else data.name}
+ DeviceType = ${data.interfaceType}
+ Device = /dev/net/tun
+ Interface = tinc.${network}
+ ${data.extraConfig}
+ '';
+ };
+ }
+ ));
+
+ networking.interfaces = flip mapAttrs' cfg.networks (network: data: nameValuePair
+ ("tinc.${network}")
+ ({
+ virtual = true;
+ virtualType = "${data.interfaceType}";
+ })
+ );
+
+ systemd.services = flip mapAttrs' cfg.networks (network: data: nameValuePair
+ ("tinc.${network}")
+ ({
+ description = "Tinc Daemon - ${network}";
+ wantedBy = [ "network.target" ];
+ after = [ "network-interfaces.target" ];
+ path = [ data.package ];
+ restartTriggers = [ config.environment.etc."tinc/${network}/tinc.conf".source ]
+ ++ mapAttrsToList (host: _ : config.environment.etc."tinc/${network}/hosts/${host}".source) data.hosts;
+ serviceConfig = {
+ Type = "simple";
+ PIDFile = "/run/tinc.${network}.pid";
+ };
+ preStart = ''
+ mkdir -p /etc/tinc/${network}/hosts
+
+ # Determine how we should generate our keys
+ if type tinc >/dev/null 2>&1; then
+ # Tinc 1.1+ uses the tinc helper application for key generation
+
+ # Prefer ED25519 keys (only in 1.1+)
+ [ -f "/etc/tinc/${network}/ed25519_key.priv" ] || tinc -n ${network} generate-ed25519-keys
+
+ # Otherwise use RSA keys
+ [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tinc -n ${network} generate-rsa-keys 4096
+ else
+ # Tinc 1.0 uses the tincd application
+ [ -f "/etc/tinc/${network}/rsa_key.priv" ] || tincd -n ${network} -K 4096
+ fi
+ '';
+ script = ''
+ tincd -D -U tinc.${network} -n ${network} --pidfile /run/tinc.${network}.pid -d ${toString data.debugLevel}
+ '';
+ })
+ );
+
+ users.extraUsers = flip mapAttrs' cfg.networks (network: _:
+ nameValuePair ("tinc.${network}") ({
+ description = "Tinc daemon user for ${network}";
+ })
+ );
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/tlsdated.nix b/nixos/modules/services/networking/tlsdated.nix
new file mode 100644
index 00000000000..f2d0c9f35c9
--- /dev/null
+++ b/nixos/modules/services/networking/tlsdated.nix
@@ -0,0 +1,110 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ inherit (pkgs) coreutils tlsdate;
+
+ cfg = config.services.tlsdated;
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.tlsdated = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable tlsdated daemon.
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = types.string;
+ description = ''
+ Additional command line arguments to pass to tlsdated.
+ '';
+ };
+
+ sources = mkOption {
+ type = types.listOf (types.submodule {
+ options = {
+ host = mkOption {
+ type = types.string;
+ description = ''
+ Remote hostname.
+ '';
+ };
+ port = mkOption {
+ type = types.int;
+ description = ''
+ Remote port.
+ '';
+ };
+ proxy = mkOption {
+ type = types.nullOr types.string;
+ default = null;
+ description = ''
+ The proxy argument expects HTTP, SOCKS4A or SOCKS5 formatted as followed:
+
+ http://127.0.0.1:8118
+ socks4a://127.0.0.1:9050
+ socks5://127.0.0.1:9050
+
+ The proxy support should not leak DNS requests and is suitable for use with Tor.
+ '';
+ };
+ };
+ });
+ default = [
+ {
+ host = "www.ptb.de";
+ port = 443;
+ proxy = null;
+ }
+ ];
+ description = ''
+ You can list one or more sources to fetch time from.
+ '';
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ # Make tools such as tlsdate available in the system path
+ environment.systemPackages = [ tlsdate ];
+
+ systemd.services.tlsdated = {
+ description = "tlsdated daemon";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ # XXX because pkgs.tlsdate is compiled to run as nobody:nogroup, we
+ # hard-code base-path to /tmp and use PrivateTmp.
+ ExecStart = "${tlsdate}/bin/tlsdated -f ${pkgs.writeText "tlsdated.confg" ''
+ base-path /tmp
+
+ ${concatMapStrings (src: ''
+ source
+ host ${src.host}
+ port ${toString src.port}
+ proxy ${if src.proxy == null then "none" else src.proxy}
+ end
+ '') cfg.sources}
+ ''} ${cfg.extraOptions}";
+ PrivateTmp = "yes";
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/networking/tox-bootstrapd.nix b/nixos/modules/services/networking/tox-bootstrapd.nix
new file mode 100644
index 00000000000..c1f945773e2
--- /dev/null
+++ b/nixos/modules/services/networking/tox-bootstrapd.nix
@@ -0,0 +1,80 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ home = "/var/lib/tox-bootstrapd";
+ PIDFile = "${home}/pid";
+
+ pkg = pkgs.libtoxcore;
+ cfg = config.services.toxBootstrapd;
+ cfgFile = builtins.toFile "tox-bootstrapd.conf"
+ ''
+ port = ${toString cfg.port}
+ keys_file_path = "${home}/keys"
+ pid_file_path = "${PIDFile}"
+ ${cfg.extraConfig}
+ '';
+in
+{
+ options =
+ { services.toxBootstrapd =
+ { enable = mkOption {
+ type = types.bool;
+ default = false;
+ description =
+ ''
+ Whether to enable the Tox DHT bootstrap daemon.
+ '';
+ };
+
+ port = mkOption {
+ type = types.int;
+ default = 33445;
+ description = "Listening port (UDP).";
+ };
+
+ keysFile = mkOption {
+ type = types.str;
+ default = "${home}/keys";
+ description = "Node key file.";
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description =
+ ''
+ Configuration for bootstrap daemon.
+ See
+ and .
+ '';
+ };
+ };
+
+ };
+
+ config = mkIf config.services.toxBootstrapd.enable {
+
+ users.extraUsers = singleton
+ { name = "tox-bootstrapd";
+ uid = config.ids.uids.tox-bootstrapd;
+ description = "Tox bootstrap daemon user";
+ inherit home;
+ createHome = true;
+ };
+
+ systemd.services.tox-bootstrapd = {
+ description = "Tox DHT bootstrap daemon";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig =
+ { ExecStart = "${pkg}/bin/tox-bootstrapd ${cfgFile}";
+ Type = "forking";
+ inherit PIDFile;
+ User = "tox-bootstrapd";
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/services/networking/unbound.nix b/nixos/modules/services/networking/unbound.nix
index 415ff13bdda..73b10c1d561 100644
--- a/nixos/modules/services/networking/unbound.nix
+++ b/nixos/modules/services/networking/unbound.nix
@@ -6,8 +6,6 @@ let
cfg = config.services.unbound;
- username = "unbound";
-
stateDir = "/var/lib/unbound";
access = concatMapStrings (x: " access-control: ${x} allow\n") cfg.allowedAccess;
@@ -21,21 +19,13 @@ let
confFile = pkgs.writeText "unbound.conf" ''
server:
directory: "${stateDir}"
- username: ${username}
- # make sure unbound can access entropy from inside the chroot.
- # e.g. on linux the use these commands (on BSD, devfs(8) is used):
- # mount --bind -n /dev/random /etc/unbound/dev/random
- # and mount --bind -n /dev/log /etc/unbound/dev/log
+ username: unbound
chroot: "${stateDir}"
- # logfile: "${stateDir}/unbound.log" #uncomment to use logfile.
- pidfile: "${stateDir}/unbound.pid"
- verbosity: 1 # uncomment and increase to get more logging.
+ pidfile: ""
${interfaces}
${access}
-
- ${forward}
-
${cfg.extraConfig}
+ ${forward}
'';
in
@@ -82,7 +72,7 @@ in
environment.systemPackages = [ pkgs.unbound ];
users.extraUsers = singleton {
- name = username;
+ name = "unbound";
uid = config.ids.uids.unbound;
description = "unbound daemon user";
home = stateDir;
@@ -96,8 +86,18 @@ in
wants = [" nss-lookup.target" ];
wantedBy = [ "multi-user.target" ];
- path = [ pkgs.unbound ];
- serviceConfig.ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${confFile}";
+ preStart = ''
+ mkdir -m 0755 -p ${stateDir}/dev/
+ cp ${confFile} ${stateDir}/unbound.conf
+ chown unbound ${stateDir}
+ touch ${stateDir}/dev/random
+ ${pkgs.utillinux}/bin/mount --bind -n /dev/random ${stateDir}/dev/random
+ '';
+
+ serviceConfig = {
+ ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${stateDir}/unbound.conf";
+ ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random";
+ };
};
};
diff --git a/nixos/modules/services/networking/unifi.nix b/nixos/modules/services/networking/unifi.nix
index 634f760328f..d6c8e0dc7a5 100644
--- a/nixos/modules/services/networking/unifi.nix
+++ b/nixos/modules/services/networking/unifi.nix
@@ -1,9 +1,24 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
with lib;
let
cfg = config.services.unifi;
stateDir = "/var/lib/unifi";
- cmd = "@${pkgs.icedtea7_jre}/bin/java java -jar ${stateDir}/lib/ace.jar";
+ cmd = "@${pkgs.jre}/bin/java java -jar ${stateDir}/lib/ace.jar";
+ mountPoints = [
+ {
+ what = "${pkgs.unifi}/dl";
+ where = "${stateDir}/dl";
+ }
+ {
+ what = "${pkgs.unifi}/lib";
+ where = "${stateDir}/lib";
+ }
+ {
+ what = "${pkgs.mongodb}/bin";
+ where = "${stateDir}/bin";
+ }
+ ];
+ systemdMountPoints = map (m: "${utils.escapeSystemdPath m.where}.mount") mountPoints;
in
{
@@ -32,30 +47,20 @@ in
# to be used as the working directory.
systemd.mounts = map ({ what, where }: {
bindsTo = [ "unifi.service" ];
- requiredBy = [ "unifi.service" ];
- before = [ "unifi.service" ];
+ partOf = [ "unifi.service" ];
+ unitConfig.RequiresMountsFor = stateDir;
options = "bind";
what = what;
where = where;
- }) [
- {
- what = "${pkgs.unifi}/dl";
- where = "${stateDir}/dl";
- }
- {
- what = "${pkgs.unifi}/lib";
- where = "${stateDir}/lib";
- }
- {
- what = "${pkgs.mongodb}/bin";
- where = "${stateDir}/bin";
- }
- ];
+ }) mountPoints;
systemd.services.unifi = {
description = "UniFi controller daemon";
wantedBy = [ "multi-user.target" ];
- after = [ "network.target" ];
+ after = [ "network.target" ] ++ systemdMountPoints;
+ partOf = systemdMountPoints;
+ bindsTo = systemdMountPoints;
+ unitConfig.RequiresMountsFor = stateDir;
preStart = ''
# Ensure privacy of state
@@ -63,13 +68,14 @@ in
chmod 0700 "${stateDir}"
# Create the volatile webapps
+ rm -rf "${stateDir}/webapps"
mkdir -p "${stateDir}/webapps"
chown unifi "${stateDir}/webapps"
ln -s "${pkgs.unifi}/webapps/ROOT.war" "${stateDir}/webapps/ROOT.war"
'';
postStop = ''
- rm "${stateDir}/webapps/ROOT.war"
+ rm -rf "${stateDir}/webapps"
'';
serviceConfig = {
diff --git a/nixos/modules/services/networking/vsftpd.nix b/nixos/modules/services/networking/vsftpd.nix
index 62b6027c012..447149552f4 100644
--- a/nixos/modules/services/networking/vsftpd.nix
+++ b/nixos/modules/services/networking/vsftpd.nix
@@ -68,6 +68,11 @@ let
Only applies if sslEnable is true. Non anonymous (local) users
must use a secure SSL connection for sending/receiving data on data connection.
'')
+ (yesNoOption "portPromiscuous" "port_promiscuous" false ''
+ Set to YES if you want to disable the PORT security check that ensures that
+ outgoing data connections can only connect to the client. Only enable if you
+ know what you are doing!
+ '')
(yesNoOption "ssl_tlsv1" "ssl_tlsv1" true '' '')
(yesNoOption "ssl_sslv2" "ssl_sslv2" false '' '')
(yesNoOption "ssl_sslv3" "ssl_sslv3" false '' '')
diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix
index 771eeecd772..e2d34ea079c 100644
--- a/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixos/modules/services/networking/wpa_supplicant.nix
@@ -31,12 +31,14 @@ in
description = ''
Whether to start wpa_supplicant to scan for
and associate with wireless networks. Note: NixOS currently
- does not generate wpa_supplicant 's
+ does not manage wpa_supplicant 's
configuration file, ${configFile} . You
should edit this file yourself to define wireless networks,
WPA keys and so on (see
wpa_supplicant.conf
- 5 ).
+ 5 ), or use
+ networking.wireless.userControlled.* to allow users to add entries
+ through wpa_cli and wpa_gui .
'';
};
@@ -62,7 +64,9 @@ in
default = false;
description = ''
Allow normal users to control wpa_supplicant through wpa_gui or wpa_cli.
- This is useful for laptop users that switch networks a lot.
+ This is useful for laptop users that switch networks a lot and don't want
+ to depend on a large package such as NetworkManager just to pick nearby
+ access points.
When you want to use this, make sure ${configFile} doesn't exist.
It will be created for you.
diff --git a/nixos/modules/services/networking/znc.nix b/nixos/modules/services/networking/znc.nix
index 2aa63c6e7df..b39aea04521 100644
--- a/nixos/modules/services/networking/znc.nix
+++ b/nixos/modules/services/networking/znc.nix
@@ -25,85 +25,6 @@ let
paths = cfg.modulePackages;
};
- confOptions = { ... }: {
- options = {
- modules = mkOption {
- type = types.listOf types.string;
- default = [ "partyline" "webadmin" "adminlog" "log" ];
- example = [ "partyline" "webadmin" "adminlog" "log" ];
- description = ''
- A list of modules to include in the `znc.conf` file.
- '';
- };
-
- userModules = mkOption {
- type = types.listOf types.string;
- default = [ ];
- example = [ "fish" "push" ];
- description = ''
- A list of user modules to include in the `znc.conf` file.
- '';
- };
-
- userName = mkOption {
- default = defaultUserName;
- example = "johntron";
- type = types.string;
- description = ''
- The user name to use when generating the `znc.conf` file.
- This is the user name used by the user logging into the ZNC web admin.
- '';
- };
-
- nick = mkOption {
- default = "znc-user";
- example = "john";
- type = types.string;
- description = ''
- The IRC nick to use when generating the `znc.conf` file.
- '';
- };
-
- passBlock = mkOption {
- default = defaultPassBlock;
- example = "Must be the block generated by the `znc --makepass` command.";
- type = types.string;
- description = ''
- The pass block to use when generating the `znc.conf` file.
- This is the password used by the user logging into the ZNC web admin.
- This is the block generated by the `znc --makepass` command.
- !!! If not specified, please change this after starting the service. !!!
- '';
- };
-
- port = mkOption {
- default = 5000;
- example = 5000;
- type = types.int;
- description = ''
- Specifies the port on which to listen.
- '';
- };
-
- useSSL = mkOption {
- default = true;
- example = true;
- type = types.bool;
- description = ''
- Indicates whether the ZNC server should use SSL when listening on the specified port.
- '';
- };
-
- extraZncConf = mkOption {
- default = "";
- type = types.lines;
- description = ''
- Extra config to `znc.conf` file
- '';
- };
- };
- };
-
# Keep znc.conf in nix store, then symlink or copy into `dataDir`, depending on `mutable`.
mkZncConf = confOpts: ''
// Also check http://en.znc.in/wiki/Configuration
@@ -211,18 +132,91 @@ in
'';
};
- confOptions = mkOption {
- default = {};
- example = {
- modules = [ "log" ];
- userName = "john";
- nick = "johntron";
+ /* TODO: add to the documentation of the current module:
+
+ Values to use when creating a `znc.conf` file.
+
+ confOptions = {
+ modules = [ "log" ];
+ userName = "john";
+ nick = "johntron";
+ };
+ */
+ confOptions = {
+ modules = mkOption {
+ type = types.listOf types.string;
+ default = [ "partyline" "webadmin" "adminlog" "log" ];
+ example = [ "partyline" "webadmin" "adminlog" "log" ];
+ description = ''
+ A list of modules to include in the `znc.conf` file.
+ '';
+ };
+
+ userModules = mkOption {
+ type = types.listOf types.string;
+ default = [ ];
+ example = [ "fish" "push" ];
+ description = ''
+ A list of user modules to include in the `znc.conf` file.
+ '';
+ };
+
+ userName = mkOption {
+ default = defaultUserName;
+ example = "johntron";
+ type = types.string;
+ description = ''
+ The user name to use when generating the `znc.conf` file.
+ This is the user name used by the user logging into the ZNC web admin.
+ '';
+ };
+
+ nick = mkOption {
+ default = "znc-user";
+ example = "john";
+ type = types.string;
+ description = ''
+ The IRC nick to use when generating the `znc.conf` file.
+ '';
+ };
+
+ passBlock = mkOption {
+ default = defaultPassBlock;
+ example = "Must be the block generated by the `znc --makepass` command.";
+ type = types.string;
+ description = ''
+ The pass block to use when generating the `znc.conf` file.
+ This is the password used by the user logging into the ZNC web admin.
+ This is the block generated by the `znc --makepass` command.
+ !!! If not specified, please change this after starting the service. !!!
+ '';
+ };
+
+ port = mkOption {
+ default = 5000;
+ example = 5000;
+ type = types.int;
+ description = ''
+ Specifies the port on which to listen.
+ '';
+ };
+
+ useSSL = mkOption {
+ default = true;
+ example = true;
+ type = types.bool;
+ description = ''
+ Indicates whether the ZNC server should use SSL when listening on the specified port.
+ '';
+ };
+
+ extraZncConf = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Extra config to `znc.conf` file
+ '';
};
- type = types.optionSet;
- description = ''
- Values to use when creating a `znc.conf` file.
- '';
- options = confOptions;
};
modulePackages = mkOption {
@@ -280,20 +274,16 @@ in
# If mutable, regenerate conf file every time.
${optionalString (!cfg.mutable) ''
- ${pkgs.coreutils}/echo "znc is set to be system-managed. Now deleting old znc.conf file to be regenerated."
- ${pkgs.coreutils}/rm -f ${cfg.dataDir}/configs/znc.conf
+ ${pkgs.coreutils}/bin/echo "znc is set to be system-managed. Now deleting old znc.conf file to be regenerated."
+ ${pkgs.coreutils}/bin/rm -f ${cfg.dataDir}/configs/znc.conf
''}
# Ensure essential files exist.
if [[ ! -f ${cfg.dataDir}/configs/znc.conf ]]; then
- ${pkgs.coreutils}/bin/echo "No znc.conf file found in ${cfg.dataDir}. Creating one now."
- ${if (!cfg.mutable)
- then "${pkgs.coreutils}/bin/ln --force -s ${zncConfFile} ${cfg.dataDir}/.znc/configs/znc.conf"
- else ''
- ${pkgs.coreutils}/bin/cp --no-clobber ${zncConfFile} ${cfg.dataDir}/configs/znc.conf
- ${pkgs.coreutils}/bin/chmod u+rw ${cfg.dataDir}/configs/znc.conf
- ${pkgs.coreutils}/bin/chown ${cfg.user} ${cfg.dataDir}/configs/znc.conf
- ''}
+ ${pkgs.coreutils}/bin/echo "No znc.conf file found in ${cfg.dataDir}. Creating one now."
+ ${pkgs.coreutils}/bin/cp --no-clobber ${zncConfFile} ${cfg.dataDir}/configs/znc.conf
+ ${pkgs.coreutils}/bin/chmod u+rw ${cfg.dataDir}/configs/znc.conf
+ ${pkgs.coreutils}/bin/chown ${cfg.user} ${cfg.dataDir}/configs/znc.conf
fi
if [[ ! -f ${cfg.dataDir}/znc.pem ]]; then
@@ -315,7 +305,6 @@ in
uid = config.ids.uids.znc;
home = cfg.dataDir;
createHome = true;
- createUser = true;
};
users.extraGroups = optional (cfg.user == defaultUser)
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index d229c610669..b573a356b35 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -4,27 +4,23 @@ with lib;
let
- inherit (pkgs) cups;
+ inherit (pkgs) cups cups_filters;
cfg = config.services.printing;
additionalBackends = pkgs.runCommand "additional-cups-backends" { }
''
mkdir -p $out
- if [ ! -e ${pkgs.cups}/lib/cups/backend/smb ]; then
+ if [ ! -e ${cups}/lib/cups/backend/smb ]; then
mkdir -p $out/lib/cups/backend
ln -sv ${pkgs.samba}/bin/smbspool $out/lib/cups/backend/smb
fi
# Provide support for printing via HTTPS.
- if [ ! -e ${pkgs.cups}/lib/cups/backend/https ]; then
+ if [ ! -e ${cups}/lib/cups/backend/https ]; then
mkdir -p $out/lib/cups/backend
- ln -sv ${pkgs.cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
+ ln -sv ${cups}/lib/cups/backend/ipp $out/lib/cups/backend/https
fi
-
- # Import filter configuration from Ghostscript.
- mkdir -p $out/share/cups/mime/
- ln -v -s "${pkgs.ghostscript}/etc/cups/"* $out/share/cups/mime/
'';
# Here we can enable additional backends, filters, etc. that are not
@@ -35,8 +31,9 @@ let
bindir = pkgs.buildEnv {
name = "cups-progs";
paths = cfg.drivers;
- pathsToLink = [ "/lib/cups" "/share/cups" "/bin" ];
+ pathsToLink = [ "/lib/cups" "/share/cups" "/bin" "/etc/cups" ];
postBuild = cfg.bindirCmds;
+ ignoreCollisions = true;
};
in
@@ -89,11 +86,61 @@ in
'';
};
+ cupsFilesConf = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ The contents of the configuration file of the CUPS daemon
+ (cups-files.conf ).
+ '';
+ };
+
+ extraConf = mkOption {
+ type = types.lines;
+ default = "";
+ example =
+ ''
+ BrowsePoll cups.example.com
+ LogLevel debug
+ '';
+ description = ''
+ Extra contents of the configuration file of the CUPS daemon
+ (cupsd.conf ).
+ '';
+ };
+
+ clientConf = mkOption {
+ type = types.lines;
+ default = "";
+ example =
+ ''
+ ServerName server.example.com
+ Encryption Never
+ '';
+ description = ''
+ The contents of the client configuration.
+ (client.conf )
+ '';
+ };
+
+ browsedConf = mkOption {
+ type = types.lines;
+ default = "";
+ example =
+ ''
+ BrowsePoll cups.example.com
+ '';
+ description = ''
+ The contents of the configuration. file of the CUPS Browsed daemon
+ (cups-browsed.conf )
+ '';
+ };
+
drivers = mkOption {
type = types.listOf types.path;
example = literalExample "[ pkgs.splix ]";
description = ''
- CUPS drivers to use. Drivers provided by CUPS, Ghostscript
+ CUPS drivers to use. Drivers provided by CUPS, cups-filters, Ghostscript
and Samba are added unconditionally.
'';
};
@@ -124,6 +171,11 @@ in
environment.systemPackages = [ cups ];
+ environment.etc."cups/client.conf".text = cfg.clientConf;
+ environment.etc."cups/cups-files.conf".text = cfg.cupsFilesConf;
+ environment.etc."cups/cupsd.conf".text = cfg.cupsdConf;
+ environment.etc."cups/cups-browsed.conf".text = cfg.browsedConf;
+
services.dbus.packages = [ cups ];
# Cups uses libusb to talk to printers, and does not use the
@@ -131,7 +183,7 @@ in
# gets loaded, and then cups cannot access the printers.
boot.blacklistedKernelModules = [ "usblp" ];
- systemd.services.cupsd =
+ systemd.services.cups =
{ description = "CUPS Printing Daemon";
wantedBy = [ "multi-user.target" ];
@@ -149,35 +201,42 @@ in
'';
serviceConfig.Type = "forking";
- serviceConfig.ExecStart = "@${cups}/sbin/cupsd cupsd -c ${pkgs.writeText "cupsd.conf" cfg.cupsdConf}";
+ serviceConfig.ExecStart = "@${cups}/sbin/cupsd cupsd";
+
+ restartTriggers =
+ [ config.environment.etc."cups/cups-files.conf".source
+ config.environment.etc."cups/cupsd.conf".source
+ ];
+ };
+
+ systemd.services.cups-browsed =
+ { description = "Make remote CUPS printers available locally";
+
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "cups.service" "avahi-daemon.service" ];
+ after = [ "cups.service" "avahi-daemon.service" ];
+
+ path = [ cups ];
+
+ serviceConfig.ExecStart = "${cups_filters}/bin/cups-browsed";
+
+ restartTriggers =
+ [ config.environment.etc."cups/cups-browsed.conf".source
+ ];
};
services.printing.drivers =
- [ pkgs.cups pkgs.cups_pdf_filter pkgs.ghostscript additionalBackends
+ [ cups pkgs.ghostscript pkgs.cups_filters additionalBackends
pkgs.perl pkgs.coreutils pkgs.gnused pkgs.bc pkgs.gawk pkgs.gnugrep
];
- services.printing.cupsdConf =
+ services.printing.cupsFilesConf =
''
- LogLevel info
-
SystemGroup root wheel
- ${concatMapStrings (addr: ''
- Listen ${addr}
- '') cfg.listenAddresses}
- Listen /var/run/cups/cups.sock
-
- # Note: we can't use ${cups}/etc/cups as the ServerRoot, since
- # CUPS will write in the ServerRoot when e.g. adding new printers
- # through the web interface.
- ServerRoot /etc/cups
-
ServerBin ${bindir}/lib/cups
DataDir ${bindir}/share/cups
- SetEnv PATH ${bindir}/lib/cups/filter:${bindir}/bin:${bindir}/sbin
-
AccessLog syslog
ErrorLog syslog
PageLog syslog
@@ -190,6 +249,18 @@ in
# these programs to run as `lp' as well.
User cups
Group lp
+ '';
+
+ services.printing.cupsdConf =
+ ''
+ LogLevel info
+
+ ${concatMapStrings (addr: ''
+ Listen ${addr}
+ '') cfg.listenAddresses}
+ Listen /var/run/cups/cups.sock
+
+ SetEnv PATH ${bindir}/lib/cups/filter:${bindir}/bin:${bindir}/sbin
Browsing On
BrowseOrder allow,deny
@@ -235,6 +306,8 @@ in
Order deny,allow
+
+ ${cfg.extraConf}
'';
security.pam.services.cups = {};
diff --git a/nixos/modules/services/scheduling/chronos.nix b/nixos/modules/services/scheduling/chronos.nix
new file mode 100644
index 00000000000..f36b886a744
--- /dev/null
+++ b/nixos/modules/services/scheduling/chronos.nix
@@ -0,0 +1,54 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.chronos;
+
+in {
+
+ ###### interface
+
+ options.services.chronos = {
+ enable = mkOption {
+ description = "Whether to enable graphite web frontend.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ httpPort = mkOption {
+ description = "Chronos listening port";
+ default = 4400;
+ type = types.int;
+ };
+
+ master = mkOption {
+ description = "Chronos mesos master zookeeper address";
+ default = "zk://${head cfg.zookeeperHosts}/mesos";
+ type = types.str;
+ };
+
+ zookeeperHosts = mkOption {
+ description = "Chronos mesos zookepper addresses";
+ default = [ "localhost:2181" ];
+ type = types.listOf types.str;
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.services.chronos = {
+ description = "Chronos Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "zookeeper.service" ];
+
+ serviceConfig = {
+ ExecStart = "${pkgs.chronos}/bin/chronos --master ${cfg.master} --zk_hosts ${concatStringsSep "," cfg.zookeeperHosts} --http_port ${toString cfg.httpPort}";
+ User = "chronos";
+ };
+ };
+
+ users.extraUsers.chronos.uid = config.ids.uids.chronos;
+ };
+}
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 9ce0bcbec7e..1f42086dc1e 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -25,6 +25,10 @@ let
sendmailPath = "/var/setuid-wrappers/sendmail";
};
+ allFiles = map (f: "\"${f}\"") (
+ [ "${systemCronJobsFile}" ] ++ config.services.cron.cronFiles
+ );
+
in
{
@@ -71,6 +75,15 @@ in
'';
};
+ cronFiles = mkOption {
+ type = types.listOf types.path;
+ default = [];
+ description = ''
+ A list of extra crontab files that will be read and appended to the main
+ crontab file when the cron service starts.
+ '';
+ };
+
};
};
@@ -78,28 +91,23 @@ in
###### implementation
- config = mkIf config.services.cron.enable {
-
- environment.etc = singleton
- # The system-wide crontab.
- { source = systemCronJobsFile;
- target = "crontab";
- mode = "0600"; # Cron requires this.
- };
+ config = mkIf (config.services.cron.enable && allFiles != []) {
security.setuidPrograms = [ "crontab" ];
environment.systemPackages = [ cronNixosPkg ];
- jobs.cron =
+ systemd.services.cron =
{ description = "Cron Daemon";
- startOn = "startup";
-
- path = [ cronNixosPkg ];
+ wantedBy = [ "multi-user.target" ];
preStart =
''
+ rm -f /etc/crontab
+ cat ${toString allFiles} > /etc/crontab
+ chmod 0600 /etc/crontab
+
mkdir -m 710 -p /var/cron
# By default, allow all users to create a crontab. This
@@ -109,7 +117,8 @@ in
fi
'';
- exec = "cron -n";
+ restartTriggers = [ config.environment.etc.localtime.source ];
+ serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
};
};
diff --git a/nixos/modules/services/scheduling/marathon.nix b/nixos/modules/services/scheduling/marathon.nix
new file mode 100644
index 00000000000..8513d1174c3
--- /dev/null
+++ b/nixos/modules/services/scheduling/marathon.nix
@@ -0,0 +1,58 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.marathon;
+
+in {
+
+ ###### interface
+
+ options.services.marathon = {
+ enable = mkOption {
+ description = "Whether to enable the marathon mesos framework.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ httpPort = mkOption {
+ description = "Marathon listening port";
+ default = 8080;
+ type = types.int;
+ };
+
+ master = mkOption {
+ description = "Marathon mesos master zookeeper address";
+ default = "zk://${head cfg.zookeeperHosts}/mesos";
+ type = types.str;
+ };
+
+ zookeeperHosts = mkOption {
+ description = "Marathon mesos zookepper addresses";
+ default = [ "localhost:2181" ];
+ type = types.listOf types.str;
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.services.marathon = {
+ description = "Marathon Service";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" "zookeeper.service" "mesos-master.service" "mesos-slave.service" ];
+
+ serviceConfig = {
+ ExecStart = "${pkgs.marathon}/bin/marathon --master ${cfg.master} --zk zk://${head cfg.zookeeperHosts}/marathon";
+ User = "marathon";
+ };
+ };
+
+ users.extraUsers.marathon = {
+ uid = config.ids.uids.marathon;
+ description = "Marathon mesos framework user";
+ };
+ };
+}
diff --git a/nixos/modules/services/search/elasticsearch.nix b/nixos/modules/services/search/elasticsearch.nix
index b74ef4370d7..12f163db463 100644
--- a/nixos/modules/services/search/elasticsearch.nix
+++ b/nixos/modules/services/search/elasticsearch.nix
@@ -135,6 +135,11 @@ in {
rm ${cfg.dataDir}/plugins || true
ln -s ${esPlugins}/plugins ${cfg.dataDir}/plugins
'';
+ postStart = mkBefore ''
+ until ${pkgs.curl}/bin/curl -s -o /dev/null ${cfg.host}:${toString cfg.port}; do
+ sleep 1
+ done
+ '';
};
environment.systemPackages = [ pkgs.elasticsearch ];
diff --git a/nixos/modules/services/search/solr.nix b/nixos/modules/services/search/solr.nix
index 38d9dedbe3c..7886d1e2e8e 100644
--- a/nixos/modules/services/search/solr.nix
+++ b/nixos/modules/services/search/solr.nix
@@ -22,7 +22,7 @@ let
cp common/lib/*.jar $out/lib/
ln -s ${pkgs.ant}/lib/ant/lib/ant.jar $out/lib/
ln -s ${cfg.solrPackage}/lib/ext/* $out/lib/
- ln -s ${pkgs.openjdk}/lib/openjdk/lib/tools.jar $out/lib/
+ ln -s ${pkgs.jdk.home}/lib/tools.jar $out/lib/
'' + optionalString (cfg.extraJars != []) ''
for f in ${concatStringsSep " " cfg.extraJars}; do
cp $f $out/lib
@@ -44,7 +44,7 @@ in {
javaPackage = mkOption {
type = types.package;
- default = pkgs.openjre;
+ default = pkgs.jre;
description = ''
Which Java derivation to use for running solr.
'';
diff --git a/nixos/modules/services/security/clamav.nix b/nixos/modules/services/security/clamav.nix
index 057891a6047..a4d54301fc1 100644
--- a/nixos/modules/services/security/clamav.nix
+++ b/nixos/modules/services/security/clamav.nix
@@ -71,10 +71,10 @@ in
mkdir -m 0755 -p ${stateDir}
chown ${clamavUser}:${clamavGroup} ${stateDir}
'';
- exec = "${pkgs.clamav}/bin/freshclam --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}";
+ exec = "${pkgs.clamav}/bin/freshclam --daemon --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}";
};
};
};
-}
\ No newline at end of file
+}
diff --git a/nixos/modules/services/security/fail2ban.nix b/nixos/modules/services/security/fail2ban.nix
index 3758652ebdd..6288b1b3ba8 100644
--- a/nixos/modules/services/security/fail2ban.nix
+++ b/nixos/modules/services/security/fail2ban.nix
@@ -40,7 +40,7 @@ in
socket = /run/fail2ban/fail2ban.sock
pidfile = /run/fail2ban/fail2ban.pid
'';
- type = types.string;
+ type = types.lines;
description =
''
The contents of Fail2ban's main configuration file. It's
@@ -64,7 +64,7 @@ in
maxretry = 5
'';
};
- type = types.attrsOf types.string;
+ type = types.attrsOf types.lines;
description =
''
The configuration of each Fail2ban “jail”. A jail
@@ -95,7 +95,7 @@ in
environment.etc."fail2ban/filter.d".source = "${pkgs.fail2ban}/etc/fail2ban/filter.d/*.conf";
systemd.services.fail2ban =
- { description = "Fail2ban intrusion prevention system";
+ { description = "Fail2ban Intrusion Prevention System";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
diff --git a/nixos/modules/services/security/fprintd.nix b/nixos/modules/services/security/fprintd.nix
new file mode 100644
index 00000000000..a35b065ba81
--- /dev/null
+++ b/nixos/modules/services/security/fprintd.nix
@@ -0,0 +1,53 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.fprintd;
+
+in
+
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.fprintd = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable fprintd daemon and PAM module for fingerprint readers handling.
+ '';
+ };
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ services.dbus.packages = [ pkgs.fprintd ];
+
+ environment.systemPackages = [ pkgs.fprintd ];
+
+ systemd.services.fprintd = {
+ description = "Fingerprint Authentication Daemon";
+
+ serviceConfig = {
+ Type = "dbus";
+ BusName = "net.reactivated.Fprint";
+ ExecStart = "${pkgs.fprintd}/libexec/fprintd";
+ };
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/security/haveged.nix b/nixos/modules/services/security/haveged.nix
index 1d52ed55dbd..2aa523bf70a 100644
--- a/nixos/modules/services/security/haveged.nix
+++ b/nixos/modules/services/security/haveged.nix
@@ -46,7 +46,7 @@ in
systemd.services.haveged =
{ description = "Entropy Harvesting Daemon";
- unitConfig.documentation = "man:haveged(8)";
+ unitConfig.Documentation = "man:haveged(8)";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.haveged ];
@@ -60,4 +60,4 @@ in
};
-}
\ No newline at end of file
+}
diff --git a/nixos/modules/services/security/munge.nix b/nixos/modules/services/security/munge.nix
new file mode 100644
index 00000000000..919c2c2b0e1
--- /dev/null
+++ b/nixos/modules/services/security/munge.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.munge;
+
+in
+
+{
+
+ ###### interface
+
+ options = {
+
+ services.munge = {
+ enable = mkEnableOption "munge service";
+
+ password = mkOption {
+ default = "/etc/munge/munge.key";
+ type = types.string;
+ description = ''
+ The path to a daemon's secret key.
+ '';
+ };
+
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ environment.systemPackages = [ pkgs.munge ];
+
+ systemd.services.munged = {
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+
+ path = [ pkgs.munge pkgs.coreutils ];
+
+ preStart = ''
+ chmod 0700 ${cfg.password}
+ mkdir -p /var/lib/munge -m 0711
+ mkdir -p /var/log/munge -m 0700
+ mkdir -p /run/munge -m 0755
+ '';
+
+ serviceConfig = {
+ ExecStart = "${pkgs.munge}/bin/munged --syslog --key-file ${cfg.password}";
+ PIDFile = "/run/munge/munged.pid";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ };
+
+ };
+
+ };
+
+}
diff --git a/nixos/modules/services/security/tor.nix b/nixos/modules/services/security/tor.nix
index 582dd124c29..47f863b96df 100644
--- a/nixos/modules/services/security/tor.nix
+++ b/nixos/modules/services/security/tor.nix
@@ -3,120 +3,146 @@
with lib;
let
-
- inherit (pkgs) tor privoxy;
-
- stateDir = "/var/lib/tor";
- privoxyDir = stateDir+"/privoxy";
-
cfg = config.services.tor;
+ torDirectory = "/var/lib/tor";
- torUser = "tor";
+ opt = name: value: optionalString (value != null) "${name} ${value}";
+ optint = name: value: optionalString (value != 0) "${name} ${toString value}";
- opt = name: value: if value != "" then "${name} ${value}" else "";
- optint = name: value: if value != 0 then "${name} ${toString value}" else "";
+ torRc = ''
+ User tor
+ DataDirectory ${torDirectory}
+ ${optint "ControlPort" cfg.controlPort}
+ ''
+ # Client connection config
+ + optionalString cfg.client.enable ''
+ SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
+ SOCKSPort ${cfg.client.socksListenAddressFaster}
+ ${opt "SocksPolicy" cfg.client.socksPolicy}
+ ''
+ # Relay config
+ + optionalString cfg.relay.enable ''
+ ORPort ${cfg.relay.portSpec}
+ ${opt "Nickname" cfg.relay.nickname}
+ ${opt "ContactInfo" cfg.relay.contactInfo}
+
+ ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
+ ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
+ ${opt "AccountingMax" cfg.relay.accountingMax}
+ ${opt "AccountingStart" cfg.relay.accountingStart}
+
+ ${if cfg.relay.isExit then
+ opt "ExitPolicy" cfg.relay.exitPolicy
+ else
+ "ExitPolicy reject *:*"}
+
+ ${optionalString cfg.relay.isBridge ''
+ BridgeRelay 1
+ ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
+ ''}
+ ''
+ + cfg.extraConfig;
+
+ torRcFile = pkgs.writeText "torrc" torRc;
in
-
{
-
- ###### interface
-
options = {
-
services.tor = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the Tor daemon. By default, the daemon is run without
+ relay, exit, bridge or client connectivity.
+ '';
+ };
- config = mkOption {
+ extraConfig = mkOption {
+ type = types.lines;
default = "";
description = ''
Extra configuration. Contents will be added verbatim to the
- configuration file.
+ configuration file at the end.
+ '';
+ };
+
+ controlPort = mkOption {
+ type = types.int;
+ default = 0;
+ example = 9051;
+ description = ''
+ If set, Tor will accept connections on the specified port
+ and allow them to control the tor process.
'';
};
client = {
-
enable = mkOption {
+ type = types.bool;
default = false;
description = ''
- Whether to enable Tor daemon to route application connections.
- You might want to disable this if you plan running a dedicated Tor relay.
+ Whether to enable Tor daemon to route application
+ connections. You might want to disable this if you plan
+ running a dedicated Tor relay.
'';
};
socksListenAddress = mkOption {
+ type = types.str;
default = "127.0.0.1:9050";
example = "192.168.0.1:9100";
description = ''
- Bind to this address to listen for connections from Socks-speaking
- applications.
+ Bind to this address to listen for connections from
+ Socks-speaking applications. Provides strong circuit
+ isolation, separate circuit per IP address.
'';
};
socksListenAddressFaster = mkOption {
+ type = types.str;
default = "127.0.0.1:9063";
+ example = "192.168.0.1:9101";
description = ''
- Same as socksListenAddress but uses weaker circuit isolation to provide
- performance suitable for a web browser.
- '';
- };
+ Bind to this address to listen for connections from
+ Socks-speaking applications. Same as socksListenAddress
+ but uses weaker circuit isolation to provide performance
+ suitable for a web browser.
+ '';
+ };
socksPolicy = mkOption {
- default = "";
+ type = types.nullOr types.str;
+ default = null;
example = "accept 192.168.0.0/16, reject *";
description = ''
- Entry policies to allow/deny SOCKS requests based on IP address.
- First entry that matches wins. If no SocksPolicy is set, we accept
- all (and only) requests from SocksListenAddress.
+ Entry policies to allow/deny SOCKS requests based on IP
+ address. First entry that matches wins. If no SocksPolicy
+ is set, we accept all (and only) requests from
+ SocksListenAddress.
'';
};
- privoxy = {
+ privoxy.enable = mkOption {
+ default = true;
+ description = ''
+ Whether to enable and configure the system Privoxy to use Tor's
+ faster port, suitable for HTTP.
- enable = mkOption {
- default = true;
- description = ''
- Whether to enable a special instance of privoxy dedicated to Tor.
- To have anonymity, protocols need to be scrubbed of identifying
- information.
- Most people using Tor want to anonymize their web traffic, so by
- default we enable an special instance of privoxy specifically for
- Tor.
- However, if you are only going to use Tor only for other kinds of
- traffic then you can disable this option.
- '';
- };
-
- listenAddress = mkOption {
- default = "127.0.0.1:8118";
- description = ''
- Address that Tor's instance of privoxy is listening to.
- *This does not configure the standard NixOS instance of privoxy.*
- This is for Tor connections only!
- See services.privoxy.listenAddress to configure the standard NixOS
- instace of privoxy.
- '';
- };
-
- config = mkOption {
- default = "";
- description = ''
- Extra configuration for Tor's instance of privoxy. Contents will be
- added verbatim to the configuration file.
- *This does not configure the standard NixOS instance of privoxy.*
- This is for Tor connections only!
- See services.privoxy.extraConfig to configure the standard NixOS
- instace of privoxy.
- '';
- };
+ To have anonymity, protocols need to be scrubbed of identifying
+ information, and this can be accomplished for HTTP by Privoxy.
+ Privoxy can also be useful for KDE torification. A good setup would be:
+ setting SOCKS proxy to the default Tor port, providing maximum
+ circuit isolation where possible; and setting HTTP proxy to Privoxy
+ to route HTTP traffic over faster, but less isolated port.
+ '';
};
-
};
relay = {
-
enable = mkOption {
+ type = types.bool;
default = false;
description = ''
Whether to enable relaying TOR traffic for others.
@@ -126,16 +152,19 @@ in
};
isBridge = mkOption {
+ type = types.bool;
default = false;
description = ''
- Bridge relays (or "bridges" ) are Tor relays that aren't listed in the
- main directory. Since there is no complete public list of them, even if an
- ISP is filtering connections to all the known Tor relays, they probably
+ Bridge relays (or "bridges") are Tor relays that aren't
+ listed in the main directory. Since there is no complete
+ public list of them, even if an ISP is filtering
+ connections to all the known Tor relays, they probably
won't be able to block all the bridges.
A bridge relay can't be an exit relay.
- You need to set relay.enable to true for this option to take effect.
+ You need to set relay.enable to true for this option to
+ take effect.
The bridge is set up with an obfuscated transport proxy.
@@ -144,25 +173,72 @@ in
};
isExit = mkOption {
+ type = types.bool;
default = false;
description = ''
- An exit relay allows Tor users to access regular Internet services.
+ An exit relay allows Tor users to access regular Internet
+ services.
- Unlike running a non-exit relay, running an exit relay may expose
- you to abuse complaints. See https://www.torproject.org/faq.html.en#ExitPolicies for more info.
+ Unlike running a non-exit relay, running an exit relay may
+ expose you to abuse complaints. See
+ https://www.torproject.org/faq.html.en#ExitPolicies for
+ more info.
- You can specify which services Tor users may access via your exit relay using exitPolicy option.
+ You can specify which services Tor users may access via
+ your exit relay using exitPolicy option.
'';
};
nickname = mkOption {
+ type = types.str;
default = "anonymous";
description = ''
A unique handle for your TOR relay.
'';
};
+ contactInfo = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "admin@relay.com";
+ description = ''
+ Contact information for the relay owner (e.g. a mail
+ address and GPG key ID).
+ '';
+ };
+
+ accountingMax = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "450 GBytes";
+ description = ''
+ Specify maximum bandwidth allowed during an accounting
+ period. This allows you to limit overall tor bandwidth
+ over some time period. See the
+ AccountingMax option by looking at the
+ tor manual (man tor ) for more.
+
+ Note this limit applies individually to upload and
+ download; if you specify "500 GBytes"
+ here, then you may transfer up to 1 TBytes of overall
+ bandwidth (500 GB upload, 500 GB download).
+ '';
+ };
+
+ accountingStart = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "month 1 1:00";
+ description = ''
+ Specify length of an accounting period. This allows you to
+ limit overall tor bandwidth over some time period. See the
+ AccountingStart option by looking at
+ the tor manual (man tor ) for more.
+ '';
+ };
+
bandwidthRate = mkOption {
+ type = types.int;
default = 0;
example = 100;
description = ''
@@ -172,6 +248,7 @@ in
};
bandwidthBurst = mkOption {
+ type = types.int;
default = cfg.relay.bandwidthRate;
example = 200;
description = ''
@@ -181,143 +258,110 @@ in
'';
};
- port = mkOption {
- default = 9001;
+ portSpec = mkOption {
+ type = types.str;
+ example = "143";
description = ''
- What port to advertise for Tor connections.
- '';
- };
+ What port to advertise for Tor connections. This corresponds
+ to the ORPort section in the Tor manual; see
+ man tor for more details.
- listenAddress = mkOption {
- default = "";
- example = "0.0.0.0:9090";
- description = ''
- Set this if you need to listen on a port other than the one advertised
- in relayPort (e.g. to advertise 443 but bind to 9090). You'll need to do
- ipchains or other port forwsarding yourself to make this work.
+ At a minimum, you should just specify the port for the
+ relay to listen on; a common one like 143, 22, 80, or 443
+ to help Tor users who may have very restrictive port-based
+ firewalls.
'';
};
exitPolicy = mkOption {
- default = "";
+ type = types.nullOr types.str;
+ default = null;
example = "accept *:6660-6667,reject *:*";
description = ''
- A comma-separated list of exit policies. They're considered first
- to last, and the first match wins. If you want to _replace_
- the default exit policy, end this with either a reject *:* or an
- accept *:*. Otherwise, you're _augmenting_ (prepending to) the
- default exit policy. Leave commented to just use the default, which is
- available in the man page or at https://www.torproject.org/documentation.html
+ A comma-separated list of exit policies. They're
+ considered first to last, and the first match wins. If you
+ want to _replace_ the default exit policy, end this with
+ either a reject *:* or an accept *:*. Otherwise, you're
+ _augmenting_ (prepending to) the default exit
+ policy. Leave commented to just use the default, which is
+ available in the man page or at
+ https://www.torproject.org/documentation.html
Look at https://www.torproject.org/faq-abuse.html#TypicalAbuses
for issues you might encounter if you use the default exit policy.
- If certain IPs and ports are blocked externally, e.g. by your firewall,
- you should update your exit policy to reflect this -- otherwise Tor
- users will be told that those destinations are down.
+ If certain IPs and ports are blocked externally, e.g. by
+ your firewall, you should update your exit policy to
+ reflect this -- otherwise Tor users will be told that
+ those destinations are down.
'';
};
-
};
-
};
-
};
-
- ###### implementation
-
- config = mkIf (cfg.client.enable || cfg.relay.enable) {
-
+ config = mkIf cfg.enable {
assertions = singleton
- { assertion = cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit);
- message = "Can't be both an exit and a bridge relay at the same time";
+ { message = "Can't be both an exit and a bridge relay at the same time";
+ assertion =
+ cfg.relay.enable -> !(cfg.relay.isBridge && cfg.relay.isExit);
};
- users.extraUsers = singleton
- { name = torUser;
- uid = config.ids.uids.tor;
- description = "Tor daemon user";
- home = stateDir;
+ users.extraGroups.tor.gid = config.ids.gids.tor;
+ users.extraUsers.tor =
+ { description = "Tor Daemon User";
+ createHome = true;
+ home = torDirectory;
+ group = "tor";
+ uid = config.ids.uids.tor;
};
- jobs = {
- tor = { name = "tor";
+ systemd.services.tor =
+ { description = "Tor Daemon";
+ path = [ pkgs.tor ];
- startOn = "started network-interfaces";
- stopOn = "stopping network-interfaces";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" ];
+ restartTriggers = [ torRcFile ];
- preStart = ''
- mkdir -m 0755 -p ${stateDir}
- chown ${torUser} ${stateDir}
- '';
- exec = "${tor}/bin/tor -f ${pkgs.writeText "torrc" cfg.config}";
- }; }
- // optionalAttrs (cfg.client.privoxy.enable && cfg.client.enable) {
- torPrivoxy = { name = "tor-privoxy";
+ # Translated from the upstream contrib/dist/tor.service.in
+ serviceConfig =
+ { Type = "simple";
+ ExecStartPre = "${pkgs.tor}/bin/tor -f ${torRcFile} --verify-config";
+ ExecStart = "${pkgs.tor}/bin/tor -f ${torRcFile} --RunAsDaemon 0";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ KillSignal = "SIGINT";
+ TimeoutSec = 30;
+ Restart = "on-failure";
+ LimitNOFILE = 32768;
- startOn = "started network-interfaces";
- stopOn = "stopping network-interfaces";
+ # Hardening
+ # Note: DevicePolicy is set to 'closed', although the
+ # minimal permissions are really:
+ # DeviceAllow /dev/null rw
+ # DeviceAllow /dev/urandom r
+ # .. but we can't specify DeviceAllow multiple times. 'closed'
+ # is close enough.
+ PrivateTmp = "yes";
+ DevicePolicy = "closed";
+ InaccessibleDirectories = "/home";
+ ReadOnlyDirectories = "/";
+ ReadWriteDirectories = torDirectory;
+ NoNewPrivileges = "yes";
+ };
+ };
- preStart = ''
- mkdir -m 0755 -p ${privoxyDir}
- chown ${torUser} ${privoxyDir}
- '';
- exec = "${privoxy}/sbin/privoxy --no-daemon --user ${torUser} ${pkgs.writeText "torPrivoxy.conf" cfg.client.privoxy.config}";
- }; };
+ environment.systemPackages = [ pkgs.tor ];
- services.tor.config = ''
- DataDirectory ${stateDir}
- User ${torUser}
- ''
- + optionalString cfg.client.enable ''
- SOCKSPort ${cfg.client.socksListenAddress} IsolateDestAddr
- SOCKSPort ${cfg.client.socksListenAddressFaster}
- ${opt "SocksPolicy" cfg.client.socksPolicy}
- ''
- + optionalString cfg.relay.enable ''
- ORPort ${toString cfg.relay.port}
- ${opt "ORListenAddress" cfg.relay.listenAddress }
- ${opt "Nickname" cfg.relay.nickname}
- ${optint "RelayBandwidthRate" cfg.relay.bandwidthRate}
- ${optint "RelayBandwidthBurst" cfg.relay.bandwidthBurst}
- ${if cfg.relay.isExit then opt "ExitPolicy" cfg.relay.exitPolicy else "ExitPolicy reject *:*"}
- ${if cfg.relay.isBridge then ''
- BridgeRelay 1
- ServerTransportPlugin obfs2,obfs3 exec ${pkgs.pythonPackages.obfsproxy}/bin/obfsproxy managed
- '' else ""}
- '';
-
- services.tor.client.privoxy.config = ''
- # Generally, this file goes in /etc/privoxy/config
- #
- # Tor listens as a SOCKS4a proxy here:
+ services.privoxy = mkIf (cfg.client.enable && cfg.client.privoxy.enable) {
+ enable = true;
+ extraConfig = ''
forward-socks4a / ${cfg.client.socksListenAddressFaster} .
- confdir ${privoxy}/etc
- logdir ${privoxyDir}
- # actionsfile standard # Internal purpose, recommended
- actionsfile default.action # Main actions file
- actionsfile user.action # User customizations
- filterfile default.filter
-
- # Don't log interesting things, only startup messages, warnings and errors
- logfile logfile
- #jarfile jarfile
- #debug 0 # show each GET/POST/CONNECT request
- debug 4096 # Startup banner and warnings
- debug 8192 # Errors - *we highly recommended enabling this*
-
- user-manual ${privoxy}/doc/privoxy/user-manual
- listen-address ${cfg.client.privoxy.listenAddress}
toggle 1
enable-remote-toggle 0
enable-edit-actions 0
enable-remote-http-toggle 0
- buffer-limit 4096
-
- # Extra config goes here
'';
-
+ };
};
-
}
diff --git a/nixos/modules/services/security/torify.nix b/nixos/modules/services/security/torify.nix
index 53f48a714b4..a81cdbbc172 100644
--- a/nixos/modules/services/security/torify.nix
+++ b/nixos/modules/services/security/torify.nix
@@ -5,13 +5,13 @@ let
cfg = config.services.tor;
torify = pkgs.writeTextFile {
- name = "torify";
+ name = "tsocks";
text = ''
#!${pkgs.stdenv.shell}
- TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
+ TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.tsocks.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
'';
executable = true;
- destination = "/bin/torify";
+ destination = "/bin/tsocks";
};
in
@@ -22,12 +22,12 @@ in
options = {
- services.tor.torify = {
+ services.tor.tsocks = {
enable = mkOption {
- default = cfg.client.enable;
+ default = cfg.enable && cfg.client.enable;
description = ''
- Whether to build torify scipt to relay application traffic via TOR.
+ Whether to build tsocks wrapper script to relay application traffic via TOR.
'';
};
@@ -53,13 +53,13 @@ in
###### implementation
- config = mkIf cfg.torify.enable {
+ config = mkIf cfg.tsocks.enable {
environment.systemPackages = [ torify ]; # expose it to the users
- services.tor.torify.config = ''
- server = ${toString(head (splitString ":" cfg.torify.server))}
- server_port = ${toString(tail (splitString ":" cfg.torify.server))}
+ services.tor.tsocks.config = ''
+ server = ${toString(head (splitString ":" cfg.tsocks.server))}
+ server_port = ${toString(tail (splitString ":" cfg.tsocks.server))}
local = 127.0.0.0/255.128.0.0
local = 127.128.0.0/255.192.0.0
diff --git a/nixos/modules/services/security/torsocks.nix b/nixos/modules/services/security/torsocks.nix
index ede6c983677..1b5a05b21e7 100644
--- a/nixos/modules/services/security/torsocks.nix
+++ b/nixos/modules/services/security/torsocks.nix
@@ -1,85 +1,121 @@
{ config, lib, pkgs, ... }:
+
with lib;
+
let
+ cfg = config.services.tor.torsocks;
+ optionalNullStr = b: v: optionalString (b != null) v;
- cfg = config.services.tor;
+ configFile = server: ''
+ TorAddress ${toString (head (splitString ":" server))}
+ TorPort ${toString (tail (splitString ":" server))}
- makeConfig = server: ''
- server = ${toString(head (splitString ":" server))}
- server_port = ${toString(tail (splitString ":" server))}
+ OnionAddrRange ${cfg.onionAddrRange}
- local = 127.0.0.0/255.128.0.0
- local = 127.128.0.0/255.192.0.0
- local = 169.254.0.0/255.255.0.0
- local = 172.16.0.0/255.240.0.0
- local = 192.168.0.0/255.255.0.0
+ ${optionalNullStr cfg.socks5Username
+ "SOCKS5Username ${cfg.socks5Username}"}
+ ${optionalNullStr cfg.socks5Password
+ "SOCKS5Password ${cfg.socks5Password}"}
- ${cfg.torsocks.config}
- '';
- makeTorsocks = name: server: pkgs.writeTextFile {
+ AllowInbound ${if cfg.allowInbound then "1" else "0"}
+ '';
+
+ wrapTorsocks = name: server: pkgs.writeTextFile {
name = name;
text = ''
#!${pkgs.stdenv.shell}
- TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" "$@"
+ TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (configFile server)} ${pkgs.torsocks}/bin/torsocks "$@"
'';
executable = true;
destination = "/bin/${name}";
};
- torsocks = makeTorsocks "torsocks" cfg.torsocks.server;
- torsocksFaster = makeTorsocks "torsocks-faster" cfg.torsocks.serverFaster;
in
-
{
-
- ###### interface
-
options = {
-
services.tor.torsocks = {
-
enable = mkOption {
- default = cfg.client.enable;
+ type = types.bool;
+ default = config.services.tor.enable && config.services.tor.client.enable;
description = ''
- Whether to build torsocks scipt to relay application traffic via TOR.
+ Whether to build /etc/tor/torsocks.conf
+ containing the specified global torsocks configuration.
'';
};
server = mkOption {
- default = cfg.client.socksListenAddress;
- example = "192.168.0.20:9050";
+ type = types.str;
+ default = "127.0.0.1:9050";
+ example = "192.168.0.20:1234";
description = ''
- IP address of TOR client to use.
+ IP/Port of the Tor SOCKS server. Currently, hostnames are
+ NOT supported by torsocks.
'';
};
- serverFaster = mkOption {
- default = cfg.client.socksListenAddressFaster;
- example = "192.168.0.20:9063";
+ fasterServer = mkOption {
+ type = types.str;
+ default = "127.0.0.1:9063";
+ example = "192.168.0.20:1234";
description = ''
- IP address of TOR client to use for applications like web browsers which
- need less circuit isolation to achive satisfactory performance.
+ IP/Port of the Tor SOCKS server for torsocks-faster wrapper suitable for HTTP.
+ Currently, hostnames are NOT supported by torsocks.
'';
};
- config = mkOption {
- default = "";
+ onionAddrRange = mkOption {
+ type = types.str;
+ default = "127.42.42.0/24";
description = ''
- Extra configuration. Contents will be added verbatim to torsocks
- configuration file.
+ Tor hidden sites do not have real IP addresses. This
+ specifies what range of IP addresses will be handed to the
+ application as "cookies" for .onion names. Of course, you
+ should pick a block of addresses which you aren't going to
+ ever need to actually connect to. This is similar to the
+ MapAddress feature of the main tor daemon.
+ '';
+ };
+
+ socks5Username = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "bob";
+ description = ''
+ SOCKS5 username. The TORSOCKS_USERNAME
+ environment variable overrides this option if it is set.
+ '';
+ };
+
+ socks5Password = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "sekret";
+ description = ''
+ SOCKS5 password. The TORSOCKS_PASSWORD
+ environment variable overrides this option if it is set.
+ '';
+ };
+
+ allowInbound = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Set Torsocks to accept inbound connections. If set to
+ true , listen() and accept() will be
+ allowed to be used with non localhost address.
'';
};
};
-
};
- ###### implementation
-
- config = mkIf cfg.torsocks.enable {
-
- environment.systemPackages = [ torsocks torsocksFaster ]; # expose it to the users
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ pkgs.torsocks (wrapTorsocks "torsocks-faster" cfg.fasterServer) ];
+ environment.etc =
+ [ { source = pkgs.writeText "torsocks.conf" (configFile cfg.server);
+ target = "tor/torsocks.conf";
+ }
+ ];
};
-
}
diff --git a/nixos/modules/services/system/cloud-init.nix b/nixos/modules/services/system/cloud-init.nix
new file mode 100644
index 00000000000..0ef31ef8a8b
--- /dev/null
+++ b/nixos/modules/services/system/cloud-init.nix
@@ -0,0 +1,152 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.services.cloud-init;
+ path = with pkgs; [ cloud-init nettools utillinux e2fsprogs shadow dmidecode openssh ];
+ configFile = pkgs.writeText "cloud-init.cfg" ''
+users:
+ - root
+
+disable_root: false
+preserve_hostname: false
+
+cloud_init_modules:
+ - migrator
+ - seed_random
+ - bootcmd
+ - write-files
+ - growpart
+ - resizefs
+ - set_hostname
+ - update_hostname
+ - update_etc_hosts
+ - ca-certs
+ - rsyslog
+ - users-groups
+
+cloud_config_modules:
+ - emit_upstart
+ - disk_setup
+ - mounts
+ - ssh-import-id
+ - set-passwords
+ - timezone
+ - disable-ec2-metadata
+ - runcmd
+ - ssh
+
+cloud_final_modules:
+ - rightscale_userdata
+ - scripts-vendor
+ - scripts-per-once
+ - scripts-per-boot
+ - scripts-per-instance
+ - scripts-user
+ - ssh-authkey-fingerprints
+ - keys-to-console
+ - phone-home
+ - final-message
+ - power-state-change
+'';
+in
+{
+ options = {
+
+ services.cloud-init = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable the cloud-init service. This services reads
+ configuration metadata in a cloud environment and configures
+ the machine according to this metadata.
+
+ This configuration is not completely compatible with the
+ NixOS way of doing configuration, as configuration done by
+ cloud-init might be overriden by a subsequent nixos-rebuild
+ call. However, some parts of cloud-init fall outside of
+ NixOS's responsibility, like filesystem resizing and ssh
+ public key provisioning, and cloud-init is useful for that
+ parts. Thus, be wary that using cloud-init in NixOS might
+ come as some cost.
+ '';
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.cloud-init-local =
+ { description = "Initial cloud-init job (pre-networking)";
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "local-fs.target" ];
+ after = [ "local-fs.target" ];
+ path = path;
+ serviceConfig =
+ { Type = "oneshot";
+ ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} init --local";
+ RemainAfterExit = "yes";
+ TimeoutSec = "0";
+ StandardOutput = "journal+console";
+ };
+ };
+
+ systemd.services.cloud-init =
+ { description = "Initial cloud-init job (metadata service crawler)";
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "local-fs.target" "cloud-init-local.service" "sshd.service" "sshd-keygen.service" ];
+ after = [ "local-fs.target" "network.target" "cloud-init-local.service" ];
+ before = [ "sshd.service" "sshd-keygen.service" ];
+ requires = [ "network.target "];
+ path = path;
+ serviceConfig =
+ { Type = "oneshot";
+ ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} init";
+ RemainAfterExit = "yes";
+ TimeoutSec = "0";
+ StandardOutput = "journal+console";
+ };
+ };
+
+ systemd.services.cloud-config =
+ { description = "Apply the settings specified in cloud-config";
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "network.target" ];
+ after = [ "network.target" "syslog.target" "cloud-config.target" ];
+
+ path = path;
+ serviceConfig =
+ { Type = "oneshot";
+ ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} modules --mode=config";
+ RemainAfterExit = "yes";
+ TimeoutSec = "0";
+ StandardOutput = "journal+console";
+ };
+ };
+
+ systemd.services.cloud-final =
+ { description = "Execute cloud user/final scripts";
+ wantedBy = [ "multi-user.target" ];
+ wants = [ "network.target" ];
+ after = [ "network.target" "syslog.target" "cloud-config.service" "rc-local.service" ];
+ requires = [ "cloud-config.target" ];
+ path = path;
+ serviceConfig =
+ { Type = "oneshot";
+ ExecStart = "${pkgs.cloud-init}/bin/cloud-init -f ${configFile} modules --mode=final";
+ RemainAfterExit = "yes";
+ TimeoutSec = "0";
+ StandardOutput = "journal+console";
+ };
+ };
+
+ systemd.targets.cloud-config =
+ { description = "Cloud-config availability";
+ requires = [ "cloud-init-local.service" "cloud-init.service" ];
+ };
+ };
+}
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index 928f16c9448..d40f7d6d05d 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -130,6 +130,9 @@ in
config.system.path
];
+ # Don't restart dbus-daemon. Bad things tend to happen if we do.
+ systemd.services.dbus.reloadIfChanged = true;
+
environment.pathsToLink = [ "/etc/dbus-1" "/share/dbus-1" ];
};
diff --git a/nixos/modules/services/system/nscd.nix b/nixos/modules/services/system/nscd.nix
index 5460e962ea2..0879d9b85bd 100644
--- a/nixos/modules/services/system/nscd.nix
+++ b/nixos/modules/services/system/nscd.nix
@@ -62,7 +62,7 @@ in
mkdir -m 0755 -p /var/db/nscd
'';
- restartTriggers = [ config.environment.etc.hosts.source ];
+ restartTriggers = [ config.environment.etc.hosts.source config.environment.etc."nsswitch.conf".source ];
serviceConfig =
{ ExecStart = "@${pkgs.glibc}/sbin/nscd nscd -f ${cfgFile}";
diff --git a/nixos/modules/services/torrent/peerflix.nix b/nixos/modules/services/torrent/peerflix.nix
new file mode 100644
index 00000000000..0360deac08b
--- /dev/null
+++ b/nixos/modules/services/torrent/peerflix.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.peerflix;
+
+ configFile = pkgs.writeText "peerflix-config.json" ''
+ {
+ "connections": 50,
+ "tmp": "${cfg.downloadDir}"
+ }
+ '';
+
+in {
+
+ ###### interface
+
+ options.services.peerflix = {
+ enable = mkOption {
+ description = "Whether to enable peerflix service.";
+ default = false;
+ type = types.uniq types.bool;
+ };
+
+ stateDir = mkOption {
+ description = "Peerflix state directory.";
+ default = "/var/lib/peerflix";
+ type = types.path;
+ };
+
+ downloadDir = mkOption {
+ description = "Peerflix temporary download directory.";
+ default = "${cfg.stateDir}/torrents";
+ type = types.path;
+ };
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+ systemd.services.peerflix = {
+ description = "Peerflix Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-interfaces.target" ];
+ environment.HOME = cfg.stateDir;
+
+ preStart = ''
+ mkdir -p "${cfg.stateDir}"/{torrents,.config/peerflix-server}
+ if [ "$(id -u)" = 0 ]; then chown -R peerflix "${cfg.stateDir}"; fi
+ ln -fs "${configFile}" "${cfg.stateDir}/.config/peerflix-server/config.json"
+ '';
+
+ serviceConfig = {
+ ExecStart = "${pkgs.nodePackages.peerflix-server}/bin/peerflix-server";
+ PermissionsStartOnly = true;
+ User = "peerflix";
+ };
+ };
+
+ users.extraUsers.peerflix.uid = config.ids.uids.peerflix;
+ };
+}
diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
index 02db4a7a5b2..135113b3ceb 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
@@ -9,28 +9,16 @@ let
homeDir = "/var/lib/transmission";
downloadDir = "${homeDir}/Downloads";
incompleteDir = "${homeDir}/.incomplete";
+
settingsDir = "${homeDir}/.config/transmission-daemon";
- settingsFile = "${settingsDir}/settings.json";
+ settingsFile = pkgs.writeText "settings.json" (builtins.toJSON fullSettings);
# Strings must be quoted, ints and bools must not (for settings.json).
toOption = x:
if x == true then "true"
else if x == false then "false"
else if isInt x then toString x
- else toString ''\"${x}\"'';
-
- # All lines in settings.json end with a ',' (comma), except for the last
- # line. This is standard JSON. But a comma can also appear *inside* some
- # fields, notably the "rpc-whitelist" field. This is difficult to handle in
- # sed so we simply ignore it and say that if you want to change the option at
- # the last line of settings.json, you have to do it manually. At this time of
- # writing, the last option is "utp-enable":true.
- attrsToSedArgs = as:
- concatStrings (concatLists (mapAttrsToList (name: value:
- #map (x: '' -e 's=\(\"${name}\":\)[^,]*\(.*\)=\1 ${toOption x}\2=' '') # breaks if comma inside value field
- map (x: '' -e 's=\(\"${name}\":\).*=\1 ${toOption x},=' '') # always append ',' (breaks last line in settings.json)
- (if isList value then value else [value]))
- as));
+ else toString ''"${x}"'';
# for users in group "transmission" to have access to torrents
fullSettings = cfg.settings // { umask = 2; };
@@ -73,7 +61,7 @@ in
boolean values must not.
See https://trac.transmissionbt.com/wiki/EditConfigFiles for
- documentation and/or look at ${settingsFile}.
+ documentation.
'';
};
@@ -88,14 +76,14 @@ in
config = mkIf cfg.enable {
systemd.services.transmission = {
description = "Transmission BitTorrent Service";
- after = [ "network.target" ] ++ optional apparmor "apparmor.service";
+ after = [ "local-fs.target" "network.target" ] ++ optional apparmor "apparmor.service";
requires = mkIf apparmor [ "apparmor.service" ];
wantedBy = [ "multi-user.target" ];
# 1) Only the "transmission" user and group have access to torrents.
# 2) Optionally update/force specific fields into the configuration file.
serviceConfig.ExecStartPre = ''
- ${pkgs.stdenv.shell} -c "chmod 770 ${homeDir} && mkdir -p ${settingsDir} ${downloadDir} ${incompleteDir} && ${pkgs.transmission}/bin/transmission-daemon -d |& sed ${attrsToSedArgs fullSettings} > ${settingsFile}.tmp && mv ${settingsFile}.tmp ${settingsFile}"
+ ${pkgs.stdenv.shell} -c "chmod 770 ${homeDir} && mkdir -p ${settingsDir} ${downloadDir} ${incompleteDir} && rm -f ${settingsDir}/settings.json && cp -f ${settingsFile} ${settingsDir}/settings.json"
'';
serviceConfig.ExecStart = "${pkgs.transmission}/bin/transmission-daemon -f --port ${toString config.services.transmission.port}";
serviceConfig.ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
diff --git a/nixos/modules/services/ttys/agetty.nix b/nixos/modules/services/ttys/agetty.nix
index df21ebbd974..3958be33df2 100644
--- a/nixos/modules/services/ttys/agetty.nix
+++ b/nixos/modules/services/ttys/agetty.nix
@@ -66,6 +66,13 @@ with lib;
restartIfChanged = false;
};
+ systemd.services."console-getty" =
+ { serviceConfig.ExecStart = "@${pkgs.utillinux}/sbin/agetty agetty --noclear --login-program ${pkgs.shadow}/bin/login --keep-baud console 115200,38400,9600 $TERM";
+ serviceConfig.Restart = "always";
+ restartIfChanged = false;
+ enable = mkDefault config.boot.isContainer;
+ };
+
environment.etc = singleton
{ # Friendly greeting on the virtual consoles.
source = pkgs.writeText "issue" ''
diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix
index 9ac28373dac..2b5cba68d45 100644
--- a/nixos/modules/services/web-servers/apache-httpd/default.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/default.nix
@@ -109,6 +109,11 @@ let
"mpm_${mainCfg.multiProcessingModule}"
"authz_core"
"unixd"
+ "cache" "cache_disk"
+ "slotmem_shm"
+ "socache_shmcb"
+ # For compatibility with old configurations, the new module mod_access_compat is provided.
+ "access_compat"
]
++ (if mainCfg.multiProcessingModule == "prefork" then [ "cgi" ] else [ "cgid" ])
++ optional enableSSL "ssl"
@@ -160,12 +165,15 @@ let
sslConf = ''
- SSLSessionCache shm:${mainCfg.stateDir}/ssl_scache(512000)
+ SSLSessionCache ${if version24 then "shmcb" else "shm"}:${mainCfg.stateDir}/ssl_scache(512000)
- SSLMutex posixsem
+ ${if version24 then "Mutex" else "SSLMutex"} posixsem
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
+
+ SSLProtocol All -SSLv2 -SSLv3
+ SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!EXP
'';
@@ -208,16 +216,12 @@ let
'';
- robotsTxt = pkgs.writeText "robots.txt" ''
- ${# If this is a vhost, the include the entries for the main server as well.
- if isMainServer then ""
- else concatMapStrings (svc: svc.robotsEntries) mainSubservices}
- ${concatMapStrings (svc: svc.robotsEntries) subservices}
- '';
-
- robotsConf = ''
- Alias /robots.txt ${robotsTxt}
- '';
+ robotsTxt =
+ concatStringsSep "\n" (filter (x: x != "") (
+ # If this is a vhost, the include the entries for the main server as well.
+ (if isMainServer then [] else [mainCfg.robotsEntries] ++ map (svc: svc.robotsEntries) mainSubservices)
+ ++ [cfg.robotsEntries]
+ ++ (map (svc: svc.robotsEntries) subservices)));
in ''
ServerName ${serverInfo.canonicalName}
@@ -245,7 +249,9 @@ let
CustomLog ${mainCfg.logDir}/access_log-${cfg.hostName} ${cfg.logFormat}
'' else ""}
- ${robotsConf}
+ ${optionalString (robotsTxt != "") ''
+ Alias /robots.txt ${pkgs.writeText "robots.txt" robotsTxt}
+ ''}
${if isMainServer || maybeDocumentRoot != null then documentRootConf else ""}
@@ -422,8 +428,7 @@ in
package = mkOption {
type = types.package;
- default = pkgs.apacheHttpd.override { mpm = mainCfg.multiProcessingModule; };
- example = literalExample "pkgs.apacheHttpd_2_4";
+ default = pkgs.apacheHttpd;
description = ''
Overridable attribute of the Apache HTTP Server package to use.
'';
@@ -595,11 +600,11 @@ in
###### implementation
config = mkIf config.services.httpd.enable {
-
+
assertions = [ { assertion = mainCfg.enableSSL == true
-> mainCfg.sslServerCert != null
&& mainCfg.sslServerKey != null;
- message = "SSL is enabled for HTTPD, but sslServerCert and/or sslServerKey haven't been specified."; }
+ message = "SSL is enabled for httpd, but sslServerCert and/or sslServerKey haven't been specified."; }
];
users.extraUsers = optionalAttrs (mainCfg.user == "wwwrun") (singleton
@@ -680,6 +685,7 @@ in
serviceConfig.Type = "forking";
serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid";
serviceConfig.Restart = "always";
+ serviceConfig.RestartSec = "5s";
};
};
diff --git a/nixos/modules/services/web-servers/apache-httpd/limesurvey.nix b/nixos/modules/services/web-servers/apache-httpd/limesurvey.nix
new file mode 100644
index 00000000000..6f1f67970f6
--- /dev/null
+++ b/nixos/modules/services/web-servers/apache-httpd/limesurvey.nix
@@ -0,0 +1,196 @@
+{ config, lib, pkgs, serverInfo, php, ... }:
+
+with lib;
+
+let
+
+ httpd = serverInfo.serverConfig.package;
+
+ version24 = !versionOlder httpd.version "2.4";
+
+ allGranted = if version24 then ''
+ Require all granted
+ '' else ''
+ Order allow,deny
+ Allow from all
+ '';
+
+ limesurveyConfig = pkgs.writeText "config.php" ''
+
+ '';
+
+ limesurveyRoot = "${pkgs.limesurvey}/share/limesurvey/";
+
+in rec {
+
+ extraConfig = ''
+ Alias ${config.urlPrefix}/tmp ${config.dataDir}/tmp
+
+
+ ${allGranted}
+ Options -Indexes +FollowSymlinks
+
+
+ Alias ${config.urlPrefix}/upload ${config.dataDir}/upload
+
+
+ ${allGranted}
+ Options -Indexes
+
+
+ ${if config.urlPrefix != "" then ''
+ Alias ${config.urlPrefix} ${limesurveyRoot}
+ '' else ''
+ RewriteEngine On
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
+ ''}
+
+
+ DirectoryIndex index.php
+
+ '';
+
+ globalEnvVars = [
+ { name = "LIMESURVEY_CONFIG"; value = limesurveyConfig; }
+ ];
+
+ documentRoot = if config.urlPrefix == "" then limesurveyRoot else null;
+
+ enablePHP = true;
+
+ options = {
+
+ id = mkOption {
+ default = "main";
+ description = ''
+ A unique identifier necessary to keep multiple owncloud server
+ instances on the same machine apart. This is used to
+ disambiguate the administrative scripts, which get names like
+ mediawiki-$id-change-password.
+ '';
+ };
+
+ urlPrefix = mkOption {
+ default = "";
+ description = "Url prefix for site.";
+ type = types.str;
+ };
+
+ dbType = mkOption {
+ default = "pgsql";
+ description = "Type of database for limesurvey, for now, only pgsql.";
+ type = types.enum ["pgsql"];
+ };
+
+ dbName = mkOption {
+ default = "limesurvey";
+ description = "Name of the database that holds the limesurvey data.";
+ type = types.str;
+ };
+
+ dbHost = mkOption {
+ default = "localhost";
+ description = "Limesurvey database host.";
+ type = types.str;
+ };
+
+ dbPort = mkOption {
+ default = 5432;
+ description = "Limesurvey database port.";
+ type = types.int;
+ };
+
+ dbUser = mkOption {
+ default = "limesurvey";
+ description = "Limesurvey database user.";
+ type = types.str;
+ };
+
+ dbPassword = mkOption {
+ example = "foobar";
+ description = "Limesurvey database password.";
+ type = types.str;
+ };
+
+ adminUser = mkOption {
+ description = "Limesurvey admin username.";
+ default = "admin";
+ type = types.str;
+ };
+
+ adminPassword = mkOption {
+ description = "Default limesurvey admin password.";
+ default = "admin";
+ type = types.str;
+ };
+
+ adminEmail = mkOption {
+ description = "Limesurvey admin email.";
+ default = "admin@admin.com";
+ type = types.str;
+ };
+
+ forceSSL = mkOption {
+ default = false;
+ description = "Force use of HTTPS connection.";
+ type = types.bool;
+ };
+
+ siteName = mkOption {
+ default = "LimeSurvey";
+ description = "LimeSurvey name of the site.";
+ type = types.str;
+ };
+
+ defaultLang = mkOption {
+ default = "en";
+ description = "LimeSurvey default language.";
+ type = types.str;
+ };
+
+ dataDir = mkOption {
+ default = "/var/lib/limesurvey";
+ description = "LimeSurvey data directory.";
+ type = types.path;
+ };
+ };
+
+ startupScript = pkgs.writeScript "limesurvey_startup.sh" ''
+ if [ ! -f ${config.dataDir}/.created ]; then
+ mkdir -p ${config.dataDir}/{tmp/runtime,tmp/assets,tmp/upload,upload}
+ chmod -R ug+rw ${config.dataDir}
+ chmod -R o-rwx ${config.dataDir}
+ chown -R wwwrun:wwwrun ${config.dataDir}
+
+ ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
+ ${pkgs.postgresql}/bin/createdb "${config.dbName}" -O "${config.dbUser}" || true
+ ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -U postgres -d postgres -c "alter user ${config.dbUser} with password '${config.dbPassword}';" || true
+
+ ${pkgs.limesurvey}/bin/limesurvey-console install '${config.adminUser}' '${config.adminPassword}' '${config.adminUser}' '${config.adminEmail}'
+
+ touch ${config.dataDir}/.created
+ fi
+ '';
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki-postgresql-fixes.patch b/nixos/modules/services/web-servers/apache-httpd/mediawiki-postgresql-fixes.patch
deleted file mode 100644
index c46d492dc7a..00000000000
--- a/nixos/modules/services/web-servers/apache-httpd/mediawiki-postgresql-fixes.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-diff --git a/includes/specials/SpecialActiveusers.php b/includes/specials/SpecialActiveusers.php
-index f739d3b..fdd8db3 100644
---- a/includes/specials/SpecialActiveusers.php
-+++ b/includes/specials/SpecialActiveusers.php
-@@ -112,7 +112,7 @@ class ActiveUsersPager extends UsersPager {
- return array(
- 'tables' => array( 'querycachetwo', 'user', 'recentchanges' ),
- 'fields' => array( 'user_name', 'user_id', 'recentedits' => 'COUNT(*)', 'qcc_title' ),
-- 'options' => array( 'GROUP BY' => array( 'qcc_title' ) ),
-+ 'options' => array( 'GROUP BY' => array( 'qcc_title', 'user_name', 'user_id' ) ),
- 'conds' => $conds
- );
- }
-@@ -349,7 +349,7 @@ class SpecialActiveUsers extends SpecialPage {
- __METHOD__,
- array(
- 'GROUP BY' => array( 'rc_user_text' ),
-- 'ORDER BY' => 'NULL' // avoid filesort
-+ 'ORDER BY' => 'lastedittime DESC'
- )
- );
- $names = array();
diff --git a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
index 76c64f8cb29..c0ed2041639 100644
--- a/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/mediawiki.nix
@@ -4,6 +4,17 @@ with lib;
let
+ httpd = serverInfo.serverConfig.package;
+
+ version24 = !versionOlder httpd.version "2.4";
+
+ allGranted = if version24 then ''
+ Require all granted
+ '' else ''
+ Order allow,deny
+ Allow from all
+ '';
+
mediawikiConfig = pkgs.writeText "LocalSettings.php"
''
- Order allow,deny
- Allow from all
+ ${allGranted}
Options -Indexes
''}
@@ -133,7 +141,7 @@ in
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
- ${concatMapStringsSep "\n" (u: "RewriteCond %{REQUEST_URI} !^${u.urlPath}") serverInfo.serverConfig.servedDirs}
+ ${concatMapStringsSep "\n" (u: "RewriteCond %{REQUEST_URI} !^${u.urlPath}") serverInfo.vhostConfig.servedDirs}
RewriteRule ${if config.enableUploads
then "!^/images"
else "^.*\$"
@@ -144,8 +152,7 @@ in
''}
- Order allow,deny
- Allow from all
+ ${allGranted}
DirectoryIndex index.php
diff --git a/nixos/modules/services/web-servers/apache-httpd/owncloud.nix b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix
new file mode 100644
index 00000000000..a5e539bc9ba
--- /dev/null
+++ b/nixos/modules/services/web-servers/apache-httpd/owncloud.nix
@@ -0,0 +1,576 @@
+{ config, lib, pkgs, serverInfo, php, ... }:
+
+with lib;
+
+let
+
+ httpd = serverInfo.serverConfig.package;
+
+ version24 = !versionOlder httpd.version "2.4";
+
+ allGranted = if version24 then ''
+ Require all granted
+ '' else ''
+ Order allow,deny
+ Allow from all
+ '';
+
+ owncloudConfig = pkgs.writeText "config.php"
+ ''
+ true,
+
+ /* Type of database, can be sqlite, mysql or pgsql */
+ "dbtype" => "${config.dbType}",
+
+ /* Name of the ownCloud database */
+ "dbname" => "${config.dbName}",
+
+ /* User to access the ownCloud database */
+ "dbuser" => "${config.dbUser}",
+
+ /* Password to access the ownCloud database */
+ "dbpassword" => "${config.dbPassword}",
+
+ /* Host running the ownCloud database. To specify a port use "HOSTNAME:####"; to specify a unix sockets use "localhost:/path/to/socket". */
+ "dbhost" => "${config.dbServer}",
+
+ /* Prefix for the ownCloud tables in the database */
+ "dbtableprefix" => "",
+
+ /* Force use of HTTPS connection (true = use HTTPS) */
+ "forcessl" => ${config.forceSSL},
+
+ /* Blacklist a specific file and disallow the upload of files with this name - WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING. */
+ "blacklisted_files" => array('.htaccess'),
+
+ /* The automatic hostname detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */
+ "overwritehost" => "${config.overwriteHost}",
+
+ /* The automatic protocol detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the protocol detection. For example "https" */
+ "overwriteprotocol" => "${config.overwriteProtocol}",
+
+ /* The automatic webroot detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. For example "/domain.tld/ownCloud". The value "/" can be used to remove the root. */
+ "overwritewebroot" => "${config.overwriteWebRoot}",
+
+ /* The automatic detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to define a manually override condition as regular expression for the remote ip address. For example "^10\.0\.0\.[1-3]$" */
+ "overwritecondaddr" => "",
+
+ /* A proxy to use to connect to the internet. For example "myproxy.org:88" */
+ "proxy" => "",
+
+ /* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */
+ "proxyuserpwd" => "",
+
+ /* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */
+ 'trusted_domains' => array('${config.trustedDomain}'),
+
+ /* Theme to use for ownCloud */
+ "theme" => "",
+
+ /* Optional ownCloud default language - overrides automatic language detection on public pages like login or shared items. This has no effect on the user's language preference configured under "personal -> language" once they have logged in */
+ "default_language" => "${config.defaultLang}",
+
+ /* Path to the parent directory of the 3rdparty directory */
+ "3rdpartyroot" => "",
+
+ /* URL to the parent directory of the 3rdparty directory, as seen by the browser */
+ "3rdpartyurl" => "",
+
+ /* Default app to open on login.
+ * This can be a comma-separated list of app ids.
+ * If the first app is not enabled for the current user,
+ * it will try with the second one and so on. If no enabled app could be found,
+ * the "files" app will be displayed instead. */
+ "defaultapp" => "${config.defaultApp}",
+
+ /* Enable the help menu item in the settings */
+ "knowledgebaseenabled" => true,
+
+ /* Enable installing apps from the appstore */
+ "appstoreenabled" => ${config.appStoreEnable},
+
+ /* URL of the appstore to use, server should understand OCS */
+ "appstoreurl" => "https://api.owncloud.com/v1",
+
+ /* Domain name used by ownCloud for the sender mail address, e.g. no-reply@example.com */
+ "mail_domain" => "${config.mailFromDomain}",
+
+ /* FROM address used by ownCloud for the sender mail address, e.g. owncloud@example.com
+ This setting overwrites the built in 'sharing-noreply' and 'lostpassword-noreply'
+ FROM addresses, that ownCloud uses
+ */
+ "mail_from_address" => "${config.mailFrom}",
+
+ /* Enable SMTP class debugging */
+ "mail_smtpdebug" => false,
+
+ /* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
+ "mail_smtpmode" => "${config.SMTPMode}",
+
+ /* Host to use for sending mail, depends on mail_smtpmode if this is used */
+ "mail_smtphost" => "${config.SMTPHost}",
+
+ /* Port to use for sending mail, depends on mail_smtpmode if this is used */
+ "mail_smtpport" => ${config.SMTPPort},
+
+ /* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */
+ "mail_smtptimeout" => ${config.SMTPTimeout},
+
+ /* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used.
+ Can be "", ssl or tls */
+ "mail_smtpsecure" => "${config.SMTPSecure}",
+
+ /* authentication needed to send mail, depends on mail_smtpmode if this is used
+ * (false = disable authentication)
+ */
+ "mail_smtpauth" => ${config.SMTPAuth},
+
+ /* authentication type needed to send mail, depends on mail_smtpmode if this is used
+ * Can be LOGIN (default), PLAIN or NTLM */
+ "mail_smtpauthtype" => "${config.SMTPAuthType}",
+
+ /* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
+ "mail_smtpname" => "${config.SMTPUser}",
+
+ /* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
+ "mail_smtppassword" => "${config.SMTPPass}",
+
+ /* memcached servers (Only used when xCache, APC and APCu are absent.) */
+ "memcached_servers" => array(
+ // hostname, port and optional weight. Also see:
+ // http://www.php.net/manual/en/memcached.addservers.php
+ // http://www.php.net/manual/en/memcached.addserver.php
+ //array('localhost', 11211),
+ //array('other.host.local', 11211),
+ ),
+
+ /* How long should ownCloud keep deleted files in the trash bin, default value: 30 days */
+ 'trashbin_retention_obligation' => 30,
+
+ /* Disable/Enable auto expire for the trash bin, by default auto expire is enabled */
+ 'trashbin_auto_expire' => true,
+
+ /* allow user to change his display name, if it is supported by the back-end */
+ 'allow_user_to_change_display_name' => true,
+
+ /* Check 3rdparty apps for malicious code fragments */
+ "appcodechecker" => true,
+
+ /* Check if ownCloud is up to date */
+ "updatechecker" => true,
+
+ /* Are we connected to the internet or are we running in a closed network? */
+ "has_internet_connection" => true,
+
+ /* Check if the ownCloud WebDAV server is working correctly. Can be disabled if not needed in special situations*/
+ "check_for_working_webdav" => true,
+
+ /* Check if .htaccess protection of data is working correctly. Can be disabled if not needed in special situations*/
+ "check_for_working_htaccess" => true,
+
+ /* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
+ "log_type" => "owncloud",
+
+ /* File for the owncloud logger to log to, (default is ownloud.log in the data dir) */
+ "logfile" => "${config.dataDir}/owncloud.log",
+
+ /* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
+ "loglevel" => "2",
+
+ /* date format to be used while writing to the owncloud logfile */
+ 'logdateformat' => 'F d, Y H:i:s',
+
+ /* timezone used while writing to the owncloud logfile (default: UTC) */
+ 'logtimezone' => '${serverInfo.fullConfig.time.timeZone}',
+
+ /* Append all database queries and parameters to the log file.
+ (watch out, this option can increase the size of your log file)*/
+ "log_query" => false,
+
+ /* Whether ownCloud should log the last successfull cron exec */
+ "cron_log" => true,
+
+ /*
+ * Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
+ * This rotates the current owncloud logfile to a new name, this way the total log usage
+ * will stay limited and older entries are available for a while longer. The
+ * total disk usage is twice the configured size.
+ * WARNING: When you use this, the log entries will eventually be lost.
+ */
+ 'log_rotate_size' => "104857600", // 104857600, // 100 MiB
+
+ /* Lifetime of the remember login cookie, default is 15 days */
+ "remember_login_cookie_lifetime" => 1296000,
+
+ /* Life time of a session after inactivity */
+ "session_lifetime" => 86400,
+
+ /*
+ * Enable/disable session keep alive when a user is logged in in the Web UI.
+ * This is achieved by sending a "heartbeat" to the server to prevent
+ * the session timing out.
+ */
+ "session_keepalive" => true,
+
+ /* Custom CSP policy, changing this will overwrite the standard policy */
+ "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *",
+
+ /* Enable/disable X-Frame-Restriction */
+ /* HIGH SECURITY RISK IF DISABLED*/
+ "xframe_restriction" => true,
+
+ /* The directory where the user data is stored, default to data in the owncloud
+ * directory. The sqlite database is also stored here, when sqlite is used.
+ */
+ "datadirectory" => "${config.dataDir}/storage",
+
+ /* The directory where the skeleton files are located. These files will be copied to the data
+ * directory of new users. Leave empty to not copy any skeleton files.
+ */
+ // "skeletondirectory" => "",
+
+ /* Enable maintenance mode to disable ownCloud
+ If you want to prevent users to login to ownCloud before you start doing some maintenance work,
+ you need to set the value of the maintenance parameter to true.
+ Please keep in mind that users who are already logged-in are kicked out of ownCloud instantly.
+ */
+ "maintenance" => false,
+
+ "apps_paths" => array(
+
+ /* Set an array of path for your apps directories
+ key 'path' is for the fs path and the key 'url' is for the http path to your
+ applications paths. 'writable' indicates whether the user can install apps in this folder.
+ You must have at least 1 app folder writable or you must set the parameter 'appstoreenabled' to false
+ */
+ array(
+ 'path'=> '${config.dataDir}/apps',
+ 'url' => '/apps',
+ 'writable' => true,
+ ),
+ ),
+ 'user_backends'=>array(
+ /*
+ array(
+ 'class'=>'OC_User_IMAP',
+ 'arguments'=>array('{imap.gmail.com:993/imap/ssl}INBOX')
+ )
+ */
+ ),
+ //links to custom clients
+ 'customclient_desktop' => ''', //http://owncloud.org/sync-clients/
+ 'customclient_android' => ''', //https://play.google.com/store/apps/details?id=com.owncloud.android
+ 'customclient_ios' => ''', //https://itunes.apple.com/us/app/owncloud/id543672169?mt=8
+
+ // PREVIEW
+ 'enable_previews' => true,
+ /* the max width of a generated preview, if value is null, there is no limit */
+ 'preview_max_x' => null,
+ /* the max height of a generated preview, if value is null, there is no limit */
+ 'preview_max_y' => null,
+ /* the max factor to scale a preview, default is set to 10 */
+ 'preview_max_scale_factor' => 10,
+ /* custom path for libreoffice / openoffice binary */
+ 'preview_libreoffice_path' => '${config.libreofficePath}',
+ /* cl parameters for libreoffice / openoffice */
+ 'preview_office_cl_parameters' => ''',
+
+ /* whether avatars should be enabled */
+ 'enable_avatars' => true,
+
+ // Extra SSL options to be used for configuration
+ 'openssl' => array(
+ 'config' => '/etc/ssl/openssl.cnf',
+ ),
+
+ // default cipher used for file encryption, currently we support AES-128-CFB and AES-256-CFB
+ 'cipher' => 'AES-256-CFB',
+
+ /* whether usage of the instance should be restricted to admin users only */
+ 'singleuser' => false,
+
+ /* all css and js files will be served by the web server statically in one js file and ons css file*/
+ 'asset-pipeline.enabled' => false,
+
+ /* where mount.json file should be stored, defaults to data/mount.json */
+ 'mount_file' => ''',
+
+ /*
+ * Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user.
+ *
+ * When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured
+ * cache directory and "$user" is the user.
+ *
+ */
+ 'cache_path' => ''',
+
+ /* EXPERIMENTAL: option whether to include external storage in quota calculation, defaults to false */
+ 'quota_include_external_storage' => false,
+
+ /*
+ * specifies how often the filesystem is checked for changes made outside owncloud
+ * 0 -> never check the filesystem for outside changes, provides a performance increase when it's certain that no changes are made directly to the filesystem
+ * 1 -> check each file or folder at most once per request, recomended for general use if outside changes might happen
+ * 2 -> check every time the filesystem is used, causes a performance hit when using external storages, not recomended for regular use
+ */
+ 'filesystem_check_changes' => 1,
+
+ /* If true, prevent owncloud from changing the cache due to changes in the filesystem for all storage */
+ 'filesystem_cache_readonly' => false,
+
+ /**
+ * define default folder for shared files and folders
+ */
+ 'share_folder' => '/',
+
+ 'version' => '${pkgs.owncloud.version}',
+
+ 'openssl' => '${pkgs.openssl}/bin/openssl'
+
+ );
+
+ '';
+
+in
+
+rec {
+
+ extraConfig =
+ ''
+ ServerName ${config.siteName}
+ ServerAdmin ${config.adminAddr}
+ DocumentRoot ${documentRoot}
+
+ RewriteEngine On
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
+
+
+ ${builtins.readFile "${pkgs.owncloud}/.htaccess"}
+
+ '';
+
+ globalEnvVars = [
+ { name = "OC_CONFIG_PATH"; value = "${config.dataDir}/config/"; }
+ ];
+
+ documentRoot = pkgs.owncloud;
+
+ enablePHP = true;
+
+ options = {
+
+ id = mkOption {
+ default = "main";
+ description = ''
+ A unique identifier necessary to keep multiple owncloud server
+ instances on the same machine apart. This is used to
+ disambiguate the administrative scripts, which get names like
+ mediawiki-$id-change-password.
+ '';
+ };
+
+ adminUser = mkOption {
+ default = "owncloud";
+ description = "The admin user name for accessing owncloud.";
+ };
+
+ adminPassword = mkOption {
+ description = "The admin password for accessing owncloud.";
+ };
+
+ dbType = mkOption {
+ default = "pgsql";
+ description = "Type of database, in NixOS, for now, only pgsql.";
+ };
+
+ dbName = mkOption {
+ default = "owncloud";
+ description = "Name of the database that holds the owncloud data.";
+ };
+
+ dbServer = mkOption {
+ default = "localhost:5432";
+ description = ''
+ The location of the database server.
+ '';
+ };
+
+ dbUser = mkOption {
+ default = "owncloud";
+ description = "The user name for accessing the database.";
+ };
+
+ dbPassword = mkOption {
+ example = "foobar";
+ description = ''
+ The password of the database user. Warning: this is stored in
+ cleartext in the Nix store!
+ '';
+ };
+
+ forceSSL = mkOption {
+ default = "false";
+ description = "Force use of HTTPS connection.";
+ };
+
+ adminAddr = mkOption {
+ default = serverInfo.serverConfig.adminAddr;
+ example = "admin@example.com";
+ description = ''
+ Emergency contact e-mail address. Defaults to the Apache
+ admin address.
+ '';
+ };
+
+ siteName = mkOption {
+ default = "owncloud";
+ example = "Foobar owncloud";
+ description = "Name of the owncloud";
+ };
+
+ trustedDomain = mkOption {
+ default = "";
+ description = "Trusted domain";
+ };
+
+ defaultLang = mkOption {
+ default = "";
+ description = "Default language";
+ };
+
+ defaultApp = mkOption {
+ default = "";
+ description = "Default application";
+ };
+
+ appStoreEnable = mkOption {
+ default = "true";
+ description = "Enable app store";
+ };
+
+ mailFrom = mkOption {
+ default = "no-reply";
+ description = "Mail from";
+ };
+
+ mailFromDomain = mkOption {
+ default = "example.xyz";
+ description = "Mail from domain";
+ };
+
+ SMTPMode = mkOption {
+ default = "smtp";
+ description = "Which mode to use for sending mail: sendmail, smtp, qmail or php.";
+ };
+
+ SMTPHost = mkOption {
+ default = "";
+ description = "SMTP host";
+ };
+
+ SMTPPort = mkOption {
+ default = "25";
+ description = "SMTP port";
+ };
+
+ SMTPTimeout = mkOption {
+ default = "10";
+ description = "SMTP mode";
+ };
+
+ SMTPSecure = mkOption {
+ default = "ssl";
+ description = "SMTP secure";
+ };
+
+ SMTPAuth = mkOption {
+ default = "true";
+ description = "SMTP auth";
+ };
+
+ SMTPAuthType = mkOption {
+ default = "LOGIN";
+ description = "SMTP auth type";
+ };
+
+ SMTPUser = mkOption {
+ default = "";
+ description = "SMTP user";
+ };
+
+ SMTPPass = mkOption {
+ default = "";
+ description = "SMTP pass";
+ };
+
+ dataDir = mkOption {
+ default = "/var/lib/owncloud";
+ description = "Data dir";
+ };
+
+ libreofficePath = mkOption {
+ default = "/usr/bin/libreoffice";
+ description = "Path for LibreOffice/OpenOffice binary.";
+ };
+
+ overwriteHost = mkOption {
+ default = "";
+ description = "The automatic hostname detection of ownCloud can fail in
+ certain reverse proxy and CLI/cron situations. This option allows to
+ manually override the automatic detection. You can also add a port.";
+ };
+
+ overwriteProtocol = mkOption {
+ default = "";
+ description = "The automatic protocol detection of ownCloud can fail in
+ certain reverse proxy and CLI/cron situations. This option allows to
+ manually override the protocol detection.";
+ };
+
+ overwriteWebRoot = mkOption {
+ default = "";
+ description = "The automatic webroot detection of ownCloud can fail in
+ certain reverse proxy and CLI/cron situations. This option allows to
+ manually override the automatic detection.";
+ };
+
+ };
+
+ startupScript = pkgs.writeScript "owncloud_startup.sh" ''
+
+ if [ ! -d ${config.dataDir}/config ]; then
+ mkdir -p ${config.dataDir}/config
+ cp ${owncloudConfig} ${config.dataDir}/config/config.php
+ mkdir -p ${config.dataDir}/storage
+ mkdir -p ${config.dataDir}/apps
+ cp -r ${pkgs.owncloud}/apps/* ${config.dataDir}/apps/
+ chmod -R ug+rw ${config.dataDir}
+ chmod -R o-rwx ${config.dataDir}
+ chown -R wwwrun:wwwrun ${config.dataDir}
+
+ ${pkgs.postgresql}/bin/createuser -s -r postgres
+ ${pkgs.postgresql}/bin/createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
+ ${pkgs.postgresql}/bin/createdb "${config.dbName}" -O "${config.dbUser}" || true
+ ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -U postgres -d postgres -c "alter user ${config.dbUser} with password '${config.dbPassword}';" || true
+
+ QUERY="CREATE TABLE appconfig (appid VARCHAR( 255 ) NOT NULL ,configkey VARCHAR( 255 ) NOT NULL ,configvalue VARCHAR( 255 ) NOT NULL); GRANT ALL ON appconfig TO ${config.dbUser}; ALTER TABLE appconfig OWNER TO ${config.dbUser};"
+ ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
+ fi
+
+ ${php}/bin/php ${pkgs.owncloud}/occ upgrade || true
+
+ chown wwwrun:wwwrun ${config.dataDir}/owncloud.log || true
+
+ QUERY="INSERT INTO groups (gid) values('admin'); INSERT INTO users (uid,password) values('${config.adminUser}','${builtins.hashString "sha1" config.adminPassword}'); INSERT INTO group_user (gid,uid) values('admin','${config.adminUser}');"
+ ${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
+ '';
+}
diff --git a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix
index b8e86334539..76f55a63e32 100644
--- a/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/per-server-options.nix
@@ -142,9 +142,19 @@ with lib;
type = types.str;
default = "common";
example = "combined";
- description = "
+ description = ''
Log format for Apache's log files. Possible values are: combined, common, referer, agent.
- ";
+ '';
+ };
+
+ robotsEntries = mkOption {
+ type = types.lines;
+ default = "";
+ example = "Disallow: /foo/";
+ description = ''
+ Specification of pages to be ignored by web crawlers. See for details.
+ '';
};
}
diff --git a/nixos/modules/services/web-servers/apache-httpd/phabricator.nix b/nixos/modules/services/web-servers/apache-httpd/phabricator.nix
index c7a9bdf68c5..e4e3aac8d41 100644
--- a/nixos/modules/services/web-servers/apache-httpd/phabricator.nix
+++ b/nixos/modules/services/web-servers/apache-httpd/phabricator.nix
@@ -1,35 +1,30 @@
{ config, lib, pkgs, ... }:
+
+with lib;
+
let
- phabricatorRoot = pkgs.stdenv.mkDerivation rec {
- version = "2014-05-12";
- name = "phabricator-${version}";
- srcLibphutil = pkgs.fetchgit {
- url = git://github.com/facebook/libphutil.git;
- rev = "2f3b5a1cf6ea464a0250d4b1c653a795a90d2716";
- sha256 = "9598cec400984dc149162f1e648814a54ea0cd34fcd529973dc83f5486fdd9fd";
- };
- srcArcanist = pkgs.fetchgit {
- url = git://github.com/facebook/arcanist.git;
- rev = "54c377448db8dbc40f0ca86d43c837d30e493485";
- sha256 = "086db3c0d1154fbad23e7c6def31fd913384ee20247b329515838b669c3028e0";
- };
- srcPhabricator = pkgs.fetchgit {
- url = git://github.com/facebook/phabricator.git;
- rev = "1644ef185ecf1e9fca3eb6b16351ef46b19d110f";
- sha256 = "e1135e4ba76d53f48aad4161563035414ed7e878f39a8a34a875a01b41b2a084";
- };
-
- buildCommand = ''
- mkdir -p $out
- cp -R ${srcLibphutil} $out/libphutil
- cp -R ${srcArcanist} $out/arcanist
- cp -R ${srcPhabricator} $out/phabricator
- '';
- };
+ phabricatorRoot = pkgs.phabricator;
in {
+
enablePHP = true;
extraApacheModules = [ "mod_rewrite" ];
DocumentRoot = "${phabricatorRoot}/phabricator/webroot";
+
+ options = {
+ git = mkOption {
+ default = true;
+ description = "Enable git repositories.";
+ };
+ mercurial = mkOption {
+ default = true;
+ description = "Enable mercurial repositories.";
+ };
+ subversion = mkOption {
+ default = true;
+ description = "Enable subversion repositories.";
+ };
+ };
+
extraConfig = ''
DocumentRoot ${phabricatorRoot}/phabricator/webroot
@@ -38,4 +33,18 @@ in {
RewriteRule ^/favicon.ico - [L,QSA]
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
'';
+
+ extraServerPath = [
+ "${pkgs.which}"
+ "${pkgs.diffutils}"
+ ] ++
+ (if config.mercurial then ["${pkgs.mercurial}"] else []) ++
+ (if config.subversion then ["${pkgs.subversion}"] else []) ++
+ (if config.git then ["${pkgs.git}"] else []);
+
+ startupScript = pkgs.writeScript "activatePhabricator" ''
+ mkdir -p /var/repo
+ chown wwwrun /var/repo
+ '';
+
}
diff --git a/nixos/modules/services/web-servers/fcgiwrap.nix b/nixos/modules/services/web-servers/fcgiwrap.nix
index 7e91e7b60ee..2c5e433003c 100644
--- a/nixos/modules/services/web-servers/fcgiwrap.nix
+++ b/nixos/modules/services/web-servers/fcgiwrap.nix
@@ -4,7 +4,6 @@ with lib;
let
cfg = config.services.fcgiwrap;
-
in {
options = {
@@ -21,29 +20,53 @@ in {
description = "Number of processes to prefork.";
};
- bindSocket = mkOption {
- type = types.string;
- default = "unix:/run/fcgiwrap.sock";
- description = ''
- Socket to bind to. Valid socket URLs are:
- unix:/path/to/socket for Unix sockets
- tcp:dot.ted.qu.ad:port for IPv4 sockets
- tcp6:[ipv6_addr]:port for IPv6 sockets
- '';
+ socketType = mkOption {
+ type = types.addCheck types.str (t: t == "unix" || t == "tcp" || t == "tcp6");
+ default = "unix";
+ description = "Socket type: 'unix', 'tcp' or 'tcp6'.";
+ };
+
+ socketAddress = mkOption {
+ type = types.str;
+ default = "/run/fcgiwrap.sock";
+ example = "1.2.3.4:5678";
+ description = "Socket address. In case of a UNIX socket, this should be its filesystem path.";
+ };
+
+ user = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = "User permissions for the socket.";
+ };
+
+ group = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = "Group permissions for the socket.";
};
};
};
config = mkIf cfg.enable {
-
systemd.services.fcgiwrap = {
after = [ "nss-user-lookup.target" ];
- wantedBy = [ "multi-user.target" ];
+ wantedBy = optional (cfg.socketType != "unix") "multi-user.target";
serviceConfig = {
- ExecStart = "${pkgs.fcgiwrap}/sbin/fcgiwrap -c ${builtins.toString cfg.preforkProcesses} -s ${cfg.bindSocket}";
- };
+ ExecStart = "${pkgs.fcgiwrap}/sbin/fcgiwrap -c ${builtins.toString cfg.preforkProcesses} ${
+ if (cfg.socketType != "unix") then "-s ${cfg.socketType}:${cfg.socketAddress}" else ""
+ }";
+ } // (if cfg.user != null && cfg.group != null then {
+ User = cfg.user;
+ Group = cfg.group;
+ } else { } );
};
+ systemd.sockets = if (cfg.socketType == "unix") then {
+ fcgiwrap = {
+ wantedBy = [ "sockets.target" ];
+ socketConfig.ListenStream = cfg.socketAddress;
+ };
+ } else { };
};
}
diff --git a/nixos/modules/services/web-servers/lighttpd/cgit.nix b/nixos/modules/services/web-servers/lighttpd/cgit.nix
index d4663781fd8..34b2fa600ad 100644
--- a/nixos/modules/services/web-servers/lighttpd/cgit.nix
+++ b/nixos/modules/services/web-servers/lighttpd/cgit.nix
@@ -44,6 +44,9 @@ in
# make the cgitrc manpage available
environment.systemPackages = [ pkgs.cgit ];
+ # declare module dependencies
+ services.lighttpd.enableModules = [ "mod_cgi" "mod_alias" "mod_setenv" ];
+
services.lighttpd.extraConfig = ''
$HTTP["url"] =~ "^/cgit" {
cgi.assign = (
diff --git a/nixos/modules/services/web-servers/lighttpd/default.nix b/nixos/modules/services/web-servers/lighttpd/default.nix
index fc9487ab485..06f310eeb93 100644
--- a/nixos/modules/services/web-servers/lighttpd/default.nix
+++ b/nixos/modules/services/web-servers/lighttpd/default.nix
@@ -8,12 +8,54 @@ let
cfg = config.services.lighttpd;
- needModRedirect = cfg.gitweb.enable;
- needModAlias = cfg.cgit.enable || cfg.gitweb.enable;
- needModSetenv = cfg.cgit.enable || cfg.gitweb.enable;
- needModCgi = cfg.cgit.enable || cfg.gitweb.enable;
- needModStatus = cfg.mod_status;
- needModUserdir = cfg.mod_userdir;
+ # List of known lighttpd modules, ordered by how the lighttpd documentation
+ # recommends them being imported:
+ # http://redmine.lighttpd.net/projects/1/wiki/Server_modulesDetails
+ #
+ # Some modules are always imported and should not appear in the config:
+ # disallowedModules = [ "mod_indexfile" "mod_dirlisting" "mod_staticfile" ];
+ #
+ # Get full module list: "ls -1 $lighttpd/lib/*.so"
+ allKnownModules = [
+ "mod_rewrite"
+ "mod_redirect"
+ "mod_alias"
+ "mod_access"
+ "mod_auth"
+ "mod_status"
+ "mod_simple_vhost"
+ "mod_evhost"
+ "mod_userdir"
+ "mod_secdownload"
+ "mod_fastcgi"
+ "mod_proxy"
+ "mod_cgi"
+ "mod_ssi"
+ "mod_compress"
+ "mod_usertrack"
+ "mod_expire"
+ "mod_rrdtool"
+ "mod_accesslog"
+ # Remaining list of modules, order assumed to be unimportant.
+ "mod_cml"
+ "mod_dirlisting"
+ "mod_evasive"
+ "mod_extforward"
+ "mod_flv_streaming"
+ "mod_magnet"
+ "mod_mysql_vhost"
+ "mod_rewrite"
+ "mod_scgi"
+ "mod_setenv"
+ "mod_trigger_b4_dl"
+ "mod_webdav"
+ ];
+
+ maybeModuleString = moduleName:
+ if elem moduleName cfg.enableModules then ''"${moduleName}"'' else "";
+
+ modulesIncludeString = concatStringsSep ",\n"
+ (filter (x: x != "") (map maybeModuleString allKnownModules));
configFile = if cfg.configText != "" then
pkgs.writeText "lighttpd.conf" ''
@@ -38,13 +80,7 @@ let
# been loaded already. So if two services were to put the same module in
# server.modules += (), that would break the lighttpd configuration.
server.modules = (
- ${optionalString needModRedirect ''"mod_redirect",''}
- ${optionalString needModAlias ''"mod_alias",''}
- ${optionalString needModSetenv ''"mod_setenv",''}
- ${optionalString needModCgi ''"mod_cgi",''}
- ${optionalString needModStatus ''"mod_status",''}
- ${optionalString needModUserdir ''"mod_userdir",''}
- "mod_accesslog"
+ ${modulesIncludeString}
)
# Logging (logs end up in systemd journal)
@@ -117,6 +153,19 @@ in
'';
};
+ enableModules = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "mod_cgi" "mod_status" ];
+ description = ''
+ List of lighttpd modules to enable. Sub-services take care of
+ enabling modules as needed, so this option is mainly for when you
+ want to add custom stuff to
+ services.lighttpd.extraConfig that depends on a
+ certain module.
+ '';
+ };
+
mod_status = mkOption {
default = false;
type = types.uniq types.bool;
@@ -152,6 +201,26 @@ in
config = mkIf cfg.enable {
+ assertions = [
+ { assertion = all (x: elem x allKnownModules) cfg.enableModules;
+ message = ''
+ One (or more) modules in services.lighttpd.enableModules are
+ unrecognized.
+
+ Known modules: ${toString allKnownModules}
+
+ services.lighttpd.enableModules: ${toString cfg.enableModules}
+ '';
+ }
+ ];
+
+ services.lighttpd.enableModules = mkMerge
+ [ (mkIf cfg.mod_status [ "mod_status" ])
+ (mkIf cfg.mod_userdir [ "mod_userdir" ])
+ # always load mod_accesslog so that we can log to the journal
+ [ "mod_accesslog" ]
+ ];
+
systemd.services.lighttpd = {
description = "Lighttpd Web Server";
after = [ "network.target" ];
diff --git a/nixos/modules/services/web-servers/lighttpd/gitweb.nix b/nixos/modules/services/web-servers/lighttpd/gitweb.nix
index c407a1d8977..ef7072ecba3 100644
--- a/nixos/modules/services/web-servers/lighttpd/gitweb.nix
+++ b/nixos/modules/services/web-servers/lighttpd/gitweb.nix
@@ -44,6 +44,9 @@ in
config = mkIf cfg.enable {
+ # declare module dependencies
+ services.lighttpd.enableModules = [ "mod_cgi" "mod_redirect" "mod_alias" "mod_setenv" ];
+
services.lighttpd.extraConfig = ''
$HTTP["url"] =~ "^/gitweb" {
cgi.assign = (
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index 7c2d3a42973..0f21ef01263 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -23,6 +23,7 @@ in
services.nginx = {
enable = mkOption {
default = false;
+ type = types.bool;
description = "
Enable the nginx Web Server.
";
@@ -70,11 +71,13 @@ in
};
user = mkOption {
+ type = types.str;
default = "nginx";
description = "User account under which nginx runs.";
};
group = mkOption {
+ type = types.str;
default = "nginx";
description = "Group account under which nginx runs.";
};
@@ -99,6 +102,9 @@ in
'';
serviceConfig = {
ExecStart = "${nginx}/bin/nginx -c ${configFile} -p ${cfg.stateDir}";
+ Restart = "on-failure";
+ RestartSec = "10s";
+ StartLimitInterval = "1min";
};
};
diff --git a/nixos/modules/services/web-servers/tomcat.nix b/nixos/modules/services/web-servers/tomcat.nix
index c2f464014ae..99460a48835 100644
--- a/nixos/modules/services/web-servers/tomcat.nix
+++ b/nixos/modules/services/web-servers/tomcat.nix
@@ -5,7 +5,7 @@ with lib;
let
cfg = config.services.tomcat;
- tomcat = pkgs.tomcat6;
+ tomcat = cfg.package;
in
{
@@ -21,6 +21,15 @@ in
description = "Whether to enable Apache Tomcat";
};
+ package = mkOption {
+ type = types.package;
+ default = pkgs.tomcat7;
+ example = lib.literalExample "pkgs.tomcat8";
+ description = ''
+ Which tomcat package to use.
+ '';
+ };
+
baseDir = mkOption {
default = "/var/tomcat";
description = "Location where Tomcat stores configuration files, webapplications and logfiles";
diff --git a/nixos/modules/services/web-servers/uwsgi.nix b/nixos/modules/services/web-servers/uwsgi.nix
new file mode 100644
index 00000000000..6e454a2dacd
--- /dev/null
+++ b/nixos/modules/services/web-servers/uwsgi.nix
@@ -0,0 +1,112 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.uwsgi;
+
+ python2Pkgs = pkgs.python2Packages.override {
+ python = pkgs.uwsgi.python2;
+ self = python2Pkgs;
+ };
+
+ python3Pkgs = pkgs.python3Packages.override {
+ python = pkgs.uwsgi.python3;
+ self = python3Pkgs;
+ };
+
+ buildCfg = c: if builtins.typeOf c != "set" then builtins.readFile c else builtins.toJSON {
+ uwsgi =
+ if c.type == "normal"
+ then {
+ pythonpath =
+ (if c ? python2Packages
+ then builtins.map (x: "${x}/${pkgs.uwsgi.python2.sitePackages}") (c.python2Packages python2Pkgs)
+ else [])
+ ++ (if c ? python3Packages
+ then builtins.map (x: "${x}/${pkgs.uwsgi.python3.sitePackages}") (c.python3Packages python3Pkgs)
+ else []);
+ plugins = cfg.plugins;
+ } // removeAttrs c [ "type" "python2Packages" "python3Packages" ]
+ else if c.type == "emperor"
+ then {
+ emperor = if builtins.typeOf c.vassals != "set" then c.vassals
+ else pkgs.buildEnv {
+ name = "vassals";
+ paths = mapAttrsToList (n: c: pkgs.writeTextDir "${n}.json" (buildCfg c)) c.vassals;
+ };
+ } // removeAttrs c [ "type" "vassals" ]
+ else abort "type should be either 'normal' or 'emperor'";
+ };
+
+ uwsgi = pkgs.uwsgi.override {
+ plugins = cfg.plugins;
+ };
+
+in {
+
+ options = {
+ services.uwsgi = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable uWSGI";
+ };
+
+ instance = mkOption {
+ type = types.attrs;
+ default = {
+ type = "normal";
+ };
+ example = literalExample ''
+ {
+ type = "emperor";
+ vassals = {
+ moin = {
+ type = "normal";
+ python2Packages = self: with self; [ moinmoin ];
+ socket = "/run/uwsgi.sock";
+ };
+ };
+ }
+ '';
+ description = ''
+ uWSGI configuration. This awaits either a path to file or a set which will be made into one.
+ If given a set, it awaits an attribute type which can be either normal
+ or emperor .
+
+ For normal mode you can specify python2Packages and
+ python3Packages as functions from libraries set into lists of libraries.
+ For emperor mode, you should use vassals attribute
+ which should be either a set of names and configurations or a path to a directory.
+ '';
+ };
+
+ plugins = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ description = "Plugins used with uWSGI";
+ };
+
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ systemd.services.uwsgi = {
+ wantedBy = [ "multi-user.target" ];
+
+ serviceConfig = {
+ Type = "notify";
+ ExecStart = "${uwsgi}/bin/uwsgi --json ${pkgs.writeText "uwsgi.json" (buildCfg cfg.instance)}";
+ ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+ ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
+ NotifyAccess = "main";
+ KillSignal = "SIGQUIT";
+ };
+
+ };
+ };
+}
diff --git a/nixos/modules/services/web-servers/winstone.nix b/nixos/modules/services/web-servers/winstone.nix
index 7f48012f158..eed16a64f2a 100644
--- a/nixos/modules/services/web-servers/winstone.nix
+++ b/nixos/modules/services/web-servers/winstone.nix
@@ -30,7 +30,7 @@ let
javaPackage = mkOption {
type = types.package;
- default = pkgs.openjre;
+ default = pkgs.jre;
description = ''
Which Java derivation to use for running Winstone.
'';
diff --git a/nixos/modules/services/web-servers/zope2.nix b/nixos/modules/services/web-servers/zope2.nix
index 21117118457..bbe4d10f83d 100644
--- a/nixos/modules/services/web-servers/zope2.nix
+++ b/nixos/modules/services/web-servers/zope2.nix
@@ -24,7 +24,7 @@ let
http_address = mkOption {
default = "localhost:8080";
type = types.string;
- description = "Give a port and adress for the HTTP server.";
+ description = "Give a port and address for the HTTP server.";
};
user = mkOption {
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index c62beca60d8..998bcd354c5 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -18,8 +18,8 @@ in
# determines the default: later modules (if enabled) are preferred.
# E.g., if KDE is enabled, it supersedes xterm.
imports = [
- ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix
- ./e17.nix ./e18.nix ./gnome3.nix ./xbmc.nix
+ ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix
+ ./e19.nix ./gnome3.nix ./kodi.nix
];
options = {
diff --git a/nixos/modules/services/x11/desktop-managers/e17.nix b/nixos/modules/services/x11/desktop-managers/e17.nix
deleted file mode 100644
index 4cac53c9c75..00000000000
--- a/nixos/modules/services/x11/desktop-managers/e17.nix
+++ /dev/null
@@ -1,30 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
- xcfg = config.services.xserver;
- cfg = xcfg.desktopManager.e17;
-
-in
-
-{
- options = {
-
- services.xserver.desktopManager.e17.enable = mkOption {
- default = false;
- example = true;
- description = "Enable support for the E17 desktop environment.";
- };
-
- };
-
-
- config = mkIf (xcfg.enable && cfg.enable) {
-
- services.dbus.packages = [ pkgs.e17.ethumb ];
-
- };
-
-}
diff --git a/nixos/modules/services/x11/desktop-managers/e18.nix b/nixos/modules/services/x11/desktop-managers/e18.nix
deleted file mode 100644
index faafd21b07d..00000000000
--- a/nixos/modules/services/x11/desktop-managers/e18.nix
+++ /dev/null
@@ -1,43 +0,0 @@
-{ config, pkgs, lib, ... }:
-
-with lib;
-
-let
-
- xcfg = config.services.xserver;
- cfg = xcfg.desktopManager.e18;
- e18_enlightenment = pkgs.e18.enlightenment.override { set_freqset_setuid = true; };
-
-in
-
-{
- options = {
-
- services.xserver.desktopManager.e18.enable = mkOption {
- default = false;
- example = true;
- description = "Enable the E18 desktop environment.";
- };
-
- };
-
- config = mkIf (xcfg.enable && cfg.enable) {
-
- environment.systemPackages = [
- pkgs.e18.efl pkgs.e18.evas pkgs.e18.emotion pkgs.e18.elementary e18_enlightenment
- pkgs.e18.terminology pkgs.e18.econnman
- ];
-
- services.xserver.desktopManager.session = [
- { name = "E18";
- start = ''
- ${e18_enlightenment}/bin/enlightenment_start
- waitPID=$!
- '';
- }];
-
- security.setuidPrograms = [ "e18_freqset" ];
-
- };
-
-}
diff --git a/nixos/modules/services/x11/desktop-managers/e19.nix b/nixos/modules/services/x11/desktop-managers/e19.nix
new file mode 100644
index 00000000000..2d5c7b192bc
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/e19.nix
@@ -0,0 +1,101 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ xcfg = config.services.xserver;
+ cfg = xcfg.desktopManager.e19;
+ e19_enlightenment = pkgs.e19.enlightenment.override { set_freqset_setuid = true; };
+ GST_PLUGIN_PATH = lib.makeSearchPath "lib/gstreamer-1.0" [
+ pkgs.gst_all_1.gst-plugins-base
+ pkgs.gst_all_1.gst-plugins-good
+ pkgs.gst_all_1.gst-plugins-bad
+ pkgs.gst_all_1.gst-libav ];
+
+in
+
+{
+ options = {
+
+ services.xserver.desktopManager.e19.enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the E19 desktop environment.";
+ };
+
+ };
+
+ config = mkIf (xcfg.enable && cfg.enable) {
+
+ environment.systemPackages = [
+ pkgs.e19.efl pkgs.e19.evas pkgs.e19.emotion pkgs.e19.elementary e19_enlightenment
+ pkgs.e19.terminology pkgs.e19.econnman
+ pkgs.xorg.xauth # used by kdesu
+ pkgs.gtk # To get GTK+'s themes.
+ pkgs.tango-icon-theme
+ pkgs.shared_mime_info
+ pkgs.gnome.gnomeicontheme
+ pkgs.xorg.xcursorthemes
+ ];
+
+ environment.pathsToLink = [ "/etc/enlightenment" "/etc/xdg" "/share/enlightenment" "/share/elementary" "/share/applications" "/share/locale" "/share/icons" "/share/themes" "/share/mime" "/share/desktop-directories" ];
+
+ services.xserver.desktopManager.session = [
+ { name = "E19";
+ start = ''
+ # Set GTK_DATA_PREFIX so that GTK+ can find the themes
+ export GTK_DATA_PREFIX=${config.system.path}
+ # find theme engines
+ export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
+ export XDG_MENU_PREFIX=enlightenment
+
+ export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"
+
+ # make available for D-BUS user services
+ #export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}:${config.system.path}/share:${pkgs.e19.efl}/share
+
+ # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
+ ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
+
+ ${e19_enlightenment}/bin/enlightenment_start
+ waitPID=$!
+ '';
+ }];
+
+ security.setuidPrograms = [ "e19_freqset" ];
+
+ environment.etc = singleton
+ { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
+ target = "X11/xkb";
+ };
+
+ fonts.fonts = [ pkgs.dejavu_fonts pkgs.ubuntu_font_family ];
+
+ services.udisks2.enable = true;
+ services.upower.enable = config.powerManagement.enable;
+
+ #services.dbus.packages = [ pkgs.efl ]; # dbus-1 folder is not in /etc but in /share, so needs fixing first
+
+ systemd.user.services.efreet =
+ { enable = true;
+ description = "org.enlightenment.Efreet";
+ serviceConfig =
+ { ExecStart = "${pkgs.e19.efl}/bin/efreetd";
+ StandardOutput = "null";
+ };
+ };
+
+ systemd.user.services.ethumb =
+ { enable = true;
+ description = "org.enlightenment.Ethumb";
+ serviceConfig =
+ { ExecStart = "${pkgs.e19.efl}/bin/ethumbd";
+ StandardOutput = "null";
+ };
+ };
+
+
+ };
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index 049c96c54e7..6398a15bfcc 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -44,9 +44,10 @@ in {
};
environment.gnome3.packageSet = mkOption {
- default = pkgs.gnome3;
+ default = null;
example = literalExample "pkgs.gnome3_12";
- description = "Which Gnome 3 package set to use.";
+ description = "Which GNOME 3 package set to use.";
+ apply = p: if p == null then pkgs.gnome3 else p;
};
environment.gnome3.excludePackages = mkOption {
@@ -77,11 +78,10 @@ in {
services.gnome3.tracker.enable = mkDefault true;
hardware.pulseaudio.enable = mkDefault true;
services.telepathy.enable = mkDefault true;
- networking.networkmanager.enable = true;
+ networking.networkmanager.enable = mkDefault true;
services.upower.enable = config.powerManagement.enable;
- services.upower.package = gnome3.upower;
- fonts.fonts = [ pkgs.dejavu_fonts ];
+ fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
services.xserver.desktopManager.session = singleton
{ name = "gnome3";
@@ -114,6 +114,9 @@ in {
# Let nautilus find extensions
export NAUTILUS_EXTENSION_DIR=${config.system.path}/lib/nautilus/extensions-3.0/
+ # Find the mouse
+ export XCURSOR_PATH=~/.icons:${config.system.path}/share/icons
+
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix
index 669ddbd904f..21b6243ba18 100644
--- a/nixos/modules/services/x11/desktop-managers/kde4.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde4.nix
@@ -7,6 +7,7 @@ let
xcfg = config.services.xserver;
cfg = xcfg.desktopManager.kde4;
xorg = pkgs.xorg;
+ kde_workspace = config.services.xserver.desktopManager.kde4.kdeWorkspacePackage;
# Disable Nepomuk and Strigi by default. As of KDE 4.7, they don't
# really work very well (e.g. searching files often fails to find
@@ -61,15 +62,14 @@ in
example = ["gstreamer" "vlc"];
description = "Which phonon multimedia backend kde should use";
};
- };
- environment.kdePackages = mkOption {
- default = [];
- example = literalExample "[ pkgs.kde4.kdesdk ]";
- type = types.listOf types.package;
- description = "This option is obsolete. Please use environment.systemPackages instead.";
+ kdeWorkspacePackage = mkOption {
+ internal = true;
+ default = pkgs.kde4.kde_workspace;
+ type = types.package;
+ description = "Custom kde-workspace, used for NixOS rebranding.";
+ };
};
-
};
@@ -108,13 +108,13 @@ in
fi
# Start KDE.
- exec ${pkgs.kde4.kdebase_workspace}/bin/startkde
+ exec ${kde_workspace}/bin/startkde
'';
};
security.setuidOwners = singleton
{ program = "kcheckpass";
- source = "${pkgs.kde4.kdebase_workspace}/lib/kde4/libexec/kcheckpass";
+ source = "${kde_workspace}/lib/kde4/libexec/kcheckpass";
owner = "root";
group = "root";
setuid = true;
@@ -124,7 +124,7 @@ in
[ pkgs.kde4.kdelibs
pkgs.kde4.kde_baseapps # Splitted kdebase
- pkgs.kde4.kde_workspace
+ kde_workspace
pkgs.kde4.kde_runtime
pkgs.kde4.konsole
pkgs.kde4.kate
@@ -144,13 +144,21 @@ in
xorg.xauth # used by kdesu
pkgs.shared_desktop_ontologies # used by nepomuk
pkgs.strigi # used by nepomuk
+ pkgs.kde4.akonadi
pkgs.mysql # used by akonadi
+ pkgs.kde4.kdepim_runtime
]
- ++ [ nepomukConfig ] ++ phononBackendPackages
- ++ config.environment.kdePackages;
+ ++ lib.optional config.hardware.pulseaudio.enable pkgs.kde4.kmix # Perhaps this should always be enabled
+ ++ lib.optional config.hardware.bluetooth.enable pkgs.kde4.bluedevil
+ ++ lib.optional config.networking.networkmanager.enable pkgs.kde4.plasma-nm
+ ++ [ nepomukConfig ] ++ phononBackendPackages;
environment.pathsToLink = [ "/share" ];
+ environment.profileRelativeEnvVars = mkIf (lib.elem "gstreamer" cfg.phononBackends) {
+ GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ];
+ };
+
environment.etc = singleton
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
target = "X11/xkb";
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
new file mode 100644
index 00000000000..02e51577e3e
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -0,0 +1,138 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ xcfg = config.services.xserver;
+ cfg = xcfg.desktopManager.kde5;
+ xorg = pkgs.xorg;
+
+ phononBackends = {
+ gstreamer = [
+ pkgs.phonon_backend_gstreamer
+ pkgs.gst_all.gstreamer
+ pkgs.gst_all.gstPluginsBase
+ pkgs.gst_all.gstPluginsGood
+ pkgs.gst_all.gstPluginsUgly
+ pkgs.gst_all.gstPluginsBad
+ pkgs.gst_all.gstFfmpeg # for mp3 playback
+ pkgs.phonon_qt5_backend_gstreamer
+ pkgs.gst_all_1.gstreamer
+ pkgs.gst_all_1.gst-plugins-base
+ pkgs.gst_all_1.gst-plugins-good
+ pkgs.gst_all_1.gst-plugins-ugly
+ pkgs.gst_all_1.gst-plugins-bad
+ pkgs.gst_all_1.gst-libav # for mp3 playback
+ ];
+
+ vlc = [
+ pkgs.phonon_qt5_backend_vlc
+ pkgs.phonon_backend_vlc
+ ];
+ };
+
+ phononBackendPackages = flip concatMap cfg.phononBackends
+ (name: attrByPath [name] (throw "unknown phonon backend `${name}'") phononBackends);
+
+ kf5 = plasma5.kf5;
+
+ plasma5 = pkgs.plasma5_stable;
+
+ kdeApps = pkgs.kdeApps_stable;
+
+in
+
+{
+ options = {
+
+ services.xserver.desktopManager.kde5 = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Enable the Plasma 5 (KDE 5) desktop environment.";
+ };
+
+ phononBackends = mkOption {
+ type = types.listOf types.str;
+ default = ["gstreamer"];
+ example = ["gstreamer" "vlc"];
+ description = ''
+ Phonon backends to use in KDE. Only the VLC and GStreamer backends are
+ available. The GStreamer backend is preferred by upstream.
+ '';
+ };
+
+ };
+
+ };
+
+
+ config = mkIf (xcfg.enable && cfg.enable) {
+
+ warnings = optional config.services.xserver.desktopManager.kde4.enable
+ "KDE 4 should not be enabled at the same time as KDE 5";
+
+ services.xserver.desktopManager.session = singleton {
+ name = "kde5";
+ bgSupport = true;
+ start = ''exec ${plasma5.startkde}/bin/startkde;'';
+ };
+
+ security.setuidOwners = singleton {
+ program = "kcheckpass";
+ source = "${plasma5.plasma-workspace}/lib/libexec/kcheckpass";
+ owner = "root";
+ group = "root";
+ setuid = true;
+ };
+
+ environment.systemPackages =
+ filter isDerivation (builtins.attrValues plasma5)
+ ++ filter isDerivation (builtins.attrValues kf5)
+ ++ [
+ pkgs.qt4 # qtconfig is the only way to set Qt 4 theme
+
+ kdeApps.kde-baseapps
+ kdeApps.kde-base-artwork
+ kdeApps.kmix
+ kdeApps.konsole
+ kdeApps.oxygen-icons
+
+ kdeApps.kde-runtime
+
+ pkgs.hicolor_icon_theme
+
+ pkgs.orion # GTK theme, nearly identical to Breeze
+ ] ++ phononBackendPackages;
+
+ environment.pathsToLink = [ "/share" ];
+
+ environment.etc = singleton {
+ source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
+ target = "X11/xkb";
+ };
+
+ environment.profileRelativeEnvVars =
+ mkIf (lib.elem "gstreamer" cfg.phononBackends)
+ {
+ GST_PLUGIN_SYSTEM_PATH = [ "/lib/gstreamer-0.10" ];
+ GST_PLUGIN_SYSTEM_PATH_1_0 = [ "/lib/gstreamer-1.0" ];
+ };
+
+ fonts.fonts = [ plasma5.oxygen-fonts ];
+
+ programs.ssh.askPassword = "${plasma5.ksshaskpass}/bin/ksshaskpass";
+
+ # Enable helpful DBus services.
+ services.udisks2.enable = true;
+ services.upower.enable = config.powerManagement.enable;
+
+ # Extra UDEV rules used by Solid
+ services.udev.packages = [ pkgs.media-player-info ];
+
+ security.pam.services.kde = { allowNullPassword = true; };
+
+ };
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/kodi.nix b/nixos/modules/services/x11/desktop-managers/kodi.nix
new file mode 100644
index 00000000000..1e30308a513
--- /dev/null
+++ b/nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.desktopManager.kodi;
+in
+
+{
+ options = {
+ services.xserver.desktopManager.kodi = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the kodi multimedia center.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.xserver.desktopManager.session = [{
+ name = "kodi";
+ start = ''
+ ${pkgs.kodi}/bin/kodi --lircdev /var/run/lirc/lircd --standalone &
+ waitPID=$!
+ '';
+ }];
+
+ environment.systemPackages = [ pkgs.kodi ];
+ };
+}
\ No newline at end of file
diff --git a/nixos/modules/services/x11/desktop-managers/xbmc.nix b/nixos/modules/services/x11/desktop-managers/xbmc.nix
deleted file mode 100644
index 97e966ca019..00000000000
--- a/nixos/modules/services/x11/desktop-managers/xbmc.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
- cfg = config.services.xserver.desktopManager.xbmc;
-in
-
-{
- options = {
- services.xserver.desktopManager.xbmc = {
- enable = mkOption {
- default = false;
- example = true;
- description = "Enable the xbmc multimedia center.";
- };
- };
- };
-
- config = mkIf cfg.enable {
- services.xserver.desktopManager.session = [{
- name = "xbmc";
- start = ''
- ${pkgs.xbmc}/bin/xbmc --lircdev /var/run/lirc/lircd --standalone &
- waitPID=$!
- '';
- }];
-
- environment.systemPackages = [ pkgs.xbmc ];
- };
-}
\ No newline at end of file
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index a72eea76239..fce5bf11f05 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -34,10 +34,6 @@ in
# Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes.
export GTK_DATA_PREFIX=${config.system.path}
- # Necessary to get xfce4-mixer to find GST's ALSA plugin.
- # Ugly.
- export GST_PLUGIN_PATH=${config.system.path}/lib
-
exec ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc}
'';
};
@@ -50,7 +46,6 @@ in
pkgs.which # Needed by the xfce's xinitrc script.
pkgs.xfce.exo
pkgs.xfce.gtk_xfce_engine
- pkgs.xfce.libxfcegui4 # For the icons.
pkgs.xfce.mousepad
pkgs.xfce.ristretto
pkgs.xfce.terminal
@@ -60,6 +55,7 @@ in
pkgs.xfce.xfce4session
pkgs.xfce.xfce4settings
pkgs.xfce.xfce4mixer
+ pkgs.xfce.xfce4volumed
pkgs.xfce.xfce4screenshooter
pkgs.xfce.xfconf
pkgs.xfce.xfdesktop
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 6e61576f501..c5012dbb5e3 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -23,6 +23,17 @@ let
pathsToLink = [ "/" ];
};
+ fontconfig = config.fonts.fontconfig;
+ xresourcesXft = pkgs.writeText "Xresources-Xft" ''
+ ${optionalString (fontconfig.dpi != 0) ''Xft.dpi: ${toString fontconfig.dpi}''}
+ Xft.antialias: ${if fontconfig.antialias then "1" else "0"}
+ Xft.rgba: ${fontconfig.subpixel.rgba}
+ Xft.lcdfilter: lcd${fontconfig.subpixel.lcdfilter}
+ Xft.hinting: ${if fontconfig.hinting.enable then "1" else "0"}
+ Xft.autohint: ${if fontconfig.hinting.autohint then "1" else "0"}
+ Xft.hintstyle: hint${fontconfig.hinting.style}
+ '';
+
# file provided by services.xserver.displayManager.session.script
xsession = wm: dm: pkgs.writeScript "xsession"
''
@@ -68,18 +79,25 @@ let
# Start PulseAudio if enabled.
${optionalString (config.hardware.pulseaudio.enable) ''
${optionalString (!config.hardware.pulseaudio.systemWide)
- "${pkgs.pulseaudio}/bin/pulseaudio --start"
+ "${config.hardware.pulseaudio.package}/bin/pulseaudio --start"
}
# Publish access credentials in the root window.
- ${pkgs.pulseaudio}/bin/pactl load-module module-x11-publish "display=$DISPLAY"
+ ${config.hardware.pulseaudio.package}/bin/pactl load-module module-x11-publish "display=$DISPLAY"
# Keep track of devices. Mostly useful for Phonon/KDE.
- ${pkgs.pulseaudio}/bin/pactl load-module module-device-manager "do_routing=1"
+ ${config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
''}
+ # Tell systemd about our $DISPLAY. This is needed by the
+ # ssh-agent unit.
+ ${config.systemd.package}/bin/systemctl --user import-environment DISPLAY
+
# Load X defaults.
- if test -e ~/.Xdefaults; then
+ ${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft}
+ if test -e ~/.Xresources; then
+ ${xorg.xrdb}/bin/xrdb -merge ~/.Xresources
+ elif test -e ~/.Xdefaults; then
${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
fi
@@ -169,14 +187,13 @@ in
xserverBin = mkOption {
type = types.path;
- default = "${xorg.xorgserver}/bin/X";
description = "Path to the X server used by display managers.";
};
xserverArgs = mkOption {
type = types.listOf types.str;
default = [];
- example = [ "-ac" "-logverbose" "-nolisten tcp" ];
+ example = [ "-ac" "-logverbose" "-verbose" "-nolisten tcp" ];
description = "List of arguments for the X server.";
apply = toString;
};
@@ -191,6 +208,14 @@ in
description = "Shell commands executed just before the window or desktop manager is started.";
};
+ hiddenUsers = mkOption {
+ type = types.listOf types.str;
+ default = [ "nobody" ];
+ description = ''
+ A list of users which will not be shown in the display manager.
+ '';
+ };
+
desktopManagerHandlesLidAndPower = mkOption {
type = types.bool;
default = true;
@@ -280,4 +305,10 @@ in
};
+ config = {
+
+ services.xserver.displayManager.xserverBin = "${xorg.xorgserver}/bin/X";
+
+ };
+
}
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index 9d14fc2e137..a7ebafa28b3 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -5,8 +5,8 @@ with lib;
let
cfg = config.services.xserver.displayManager;
- gdm = pkgs.gnome3_12.gdm; # gdm 3.10 not supported
gnome3 = config.environment.gnome3.packageSet;
+ gdm = gnome3.gdm;
in
@@ -55,6 +55,8 @@ in
GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}";
GDM_SESSIONS_DIR = "${cfg.session.desktops}";
XDG_CONFIG_DIRS = "${gnome3.gnome_settings_daemon}/etc/xdg";
+ # Find the mouse
+ XCURSOR_PATH = "~/.icons:${config.system.path}/share/icons";
};
execCmd = "exec ${gdm}/sbin/gdm";
};
@@ -93,15 +95,23 @@ in
auth required pam_succeed_if.so uid >= 1000 quiet
auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so
- auth sufficient pam_unix.so nullok likeauth
- auth required pam_deny.so
+ auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
+ ${optionalString config.security.pam.enableEcryptfs
+ "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
+
+ ${optionalString (! config.security.pam.enableEcryptfs)
+ "auth required pam_deny.so"}
account sufficient pam_unix.so
password requisite pam_unix.so nullok sha512
+ ${optionalString config.security.pam.enableEcryptfs
+ "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_unix.so
+ ${optionalString config.security.pam.enableEcryptfs
+ "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
session required pam_loginuid.so
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start
@@ -113,15 +123,22 @@ in
auth required pam_succeed_if.so uid >= 1000 quiet
auth optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so
- auth sufficient pam_unix.so nullok likeauth
- auth required pam_deny.so
+ auth ${if config.security.pam.enableEcryptfs then "required" else "sufficient"} pam_unix.so nullok likeauth
+ ${optionalString config.security.pam.enableEcryptfs
+ "auth required ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
+ ${optionalString (! config.security.pam.enableEcryptfs)
+ "auth required pam_deny.so"}
account sufficient pam_unix.so
password requisite pam_unix.so nullok sha512
+ ${optionalString config.security.pam.enableEcryptfs
+ "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_unix.so
+ ${optionalString config.security.pam.enableEcryptfs
+ "session optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
session required pam_loginuid.so
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
session optional ${gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start
diff --git a/nixos/modules/services/x11/display-managers/kdm.nix b/nixos/modules/services/x11/display-managers/kdm.nix
index 7ec489ae3e7..d0b69c5452c 100644
--- a/nixos/modules/services/x11/display-managers/kdm.nix
+++ b/nixos/modules/services/x11/display-managers/kdm.nix
@@ -38,7 +38,7 @@ let
''}
[X-*-Greeter]
- HiddenUsers=root,nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10
+ HiddenUsers=root,${concatStringsSep "," dmcfg.hiddenUsers}
PluginsLogin=${kdebase_workspace}/lib/kde4/kgreet_classic.so
${optionalString (cfg.themeDirectory != null)
''
@@ -151,6 +151,9 @@ in
description = "KDM user";
};
+ environment.systemPackages =
+ [ pkgs.kde4.kde_wallpapers ]; # contains kdm's default background
+
};
}
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
index f8ce06738fe..6a7b810261d 100644
--- a/nixos/modules/services/x11/display-managers/lightdm.nix
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -18,6 +18,9 @@ let
exec ${dmcfg.xserverBin} ${dmcfg.xserverArgs}
'';
+ theme = pkgs.gnome3.gnome_themes_standard;
+ icons = pkgs.gnome3.gnome_icon_theme;
+
# The default greeter provided with this expression is the GTK greeter.
# Again, we need a few things in the environment for the greeter to run with
# fonts/icons.
@@ -26,20 +29,16 @@ let
buildInputs = [ pkgs.makeWrapper ];
buildCommand = ''
- mkdir -p $out/gtk-3.0/
-
- # This wrapper ensures that we actually get fonts
+ # This wrapper ensures that we actually get themes
makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \
$out/greeter \
- --set XDG_DATA_DIRS ${pkgs.gnome2.gnome_icon_theme}/share \
- --set FONTCONFIG_FILE /etc/fonts/fonts.conf \
- --set XDG_CONFIG_HOME $out/
-
- # We need this to ensure that it actually tries to find icons from gnome-icon-theme
- cat - > $out/gtk-3.0/settings.ini << EOF
- [Settings]
- gtk-icon-theme-name=gnome
- EOF
+ --prefix PATH : "${pkgs.glibc}/bin" \
+ --set GDK_PIXBUF_MODULE_FILE "$(find ${theme} -name loaders.cache)" \
+ --set GTK_PATH "${theme}:${pkgs.gtk3}" \
+ --set GTK_EXE_PREFIX "${theme}" \
+ --set GTK_DATA_PREFIX "${theme}" \
+ --set XDG_DATA_DIRS "${theme}/share:${icons}/share" \
+ --set XDG_CONFIG_HOME "${theme}/share"
cat - > $out/lightdm-gtk-greeter.desktop << EOF
[Desktop Entry]
@@ -51,6 +50,14 @@ let
'';
};
+ usersConf = writeText "users.conf"
+ ''
+ [UserList]
+ minimum-uid=500
+ hidden-users=${concatStringsSep " " dmcfg.hiddenUsers}
+ hidden-shells=/run/current-system/sw/bin/nologin
+ '';
+
lightdmConf = writeText "lightdm.conf"
''
[LightDM]
@@ -64,10 +71,19 @@ let
greeter-session = ${cfg.greeter.name}
'';
+ gtkGreeterConf = writeText "lightdm-gtk-greeter.conf"
+ ''
+ [greeter]
+ theme-name = Adwaita
+ icon-theme-name = Adwaita
+ background = ${cfg.background}
+ '';
+
in
{
options = {
services.xserver.displayManager.lightdm = {
+
enable = mkOption {
default = false;
description = ''
@@ -85,6 +101,14 @@ in
package = wrappedGtkGreeter;
};
};
+
+ background = mkOption {
+ default = "${pkgs.nixos-artwork}/gnome/Gnome_Dark.png";
+ description = ''
+ The background image or color to use.
+ '';
+ };
+
};
};
@@ -98,10 +122,14 @@ in
# lightdm relaunches itself via just `lightdm`, so needs to be on the PATH
execCmd = ''
export PATH=${lightdm}/sbin:$PATH
- ${lightdm}/sbin/lightdm --log-dir=/var/log --run-dir=/run --config=${lightdmConf}
+ exec ${lightdm}/sbin/lightdm --log-dir=/var/log --run-dir=/run
'';
};
+ environment.etc."lightdm/lightdm-gtk-greeter.conf".source = gtkGreeterConf;
+ environment.etc."lightdm/lightdm.conf".source = lightdmConf;
+ environment.etc."lightdm/users.conf".source = usersConf;
+
services.dbus.enable = true;
services.dbus.packages = [ lightdm ];
@@ -110,7 +138,7 @@ in
users.extraUsers.lightdm = {
createHome = true;
- home = "/var/lib/lightdm";
+ home = "/var/lib/lightdm-data";
group = "lightdm";
uid = config.ids.uids.lightdm;
};
diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix
new file mode 100644
index 00000000000..c44383cc611
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/sddm.nix
@@ -0,0 +1,110 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ xcfg = config.services.xserver;
+ dmcfg = xcfg.displayManager;
+ cfg = dmcfg.sddm;
+ xEnv = config.systemd.services."display-manager".environment;
+
+ xserverWrapper = pkgs.writeScript "xserver-wrapper" ''
+ #!/bin/sh
+ ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)}
+ exec ${dmcfg.xserverBin} ${dmcfg.xserverArgs} "$@"
+ '';
+
+ cfgFile = pkgs.writeText "sddm.conf" ''
+ [General]
+ HaltCommand=${pkgs.systemd}/bin/systemctl poweroff
+ RebootCommand=${pkgs.systemd}/bin/systemctl reboot
+
+ [Theme]
+ Current=${cfg.theme}
+
+ [Users]
+ MaximumUid=${toString config.ids.uids.nixbld}
+ HideUsers=${concatStringsSep "," dmcfg.hiddenUsers}
+ HideShells=/run/current-system/sw/bin/nologin
+
+ [XDisplay]
+ MinimumVT=${toString xcfg.tty}
+ ServerPath=${xserverWrapper}
+ XephyrPath=${pkgs.xorg.xorgserver}/bin/Xephyr
+ SessionCommand=${dmcfg.session.script}
+ SessionDir=${dmcfg.session.desktops}
+ XauthPath=${pkgs.xorg.xauth}/bin/xauth
+ '';
+
+in
+{
+ options = {
+
+ services.xserver.displayManager.sddm = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable sddm as the display manager.
+ '';
+ };
+
+ theme = mkOption {
+ type = types.str;
+ default = "maui";
+ description = ''
+ Greeter theme to use.
+ '';
+ };
+ };
+
+ };
+
+ config = mkIf cfg.enable {
+
+ services.xserver.displayManager.slim.enable = false;
+
+ services.xserver.displayManager.job = {
+ logsXsession = true;
+
+ #execCmd = "${pkgs.sddm}/bin/sddm";
+ execCmd = "exec ${pkgs.sddm}/bin/sddm";
+ };
+
+ security.pam.services = {
+ sddm = {
+ allowNullPassword = true;
+ startSession = true;
+ };
+
+ sddm-greeter.text = ''
+ auth required pam_succeed_if.so audit quiet_success user = sddm
+ auth optional pam_permit.so
+
+ account required pam_succeed_if.so audit quiet_success user = sddm
+ account sufficient pam_unix.so
+
+ password required pam_deny.so
+
+ session required pam_succeed_if.so audit quiet_success user = sddm
+ session required pam_env.so envfile=${config.system.build.pamEnvironment}
+ session optional ${pkgs.systemd}/lib/security/pam_systemd.so
+ session optional pam_keyinit.so force revoke
+ session optional pam_permit.so
+ '';
+ };
+
+ users.extraUsers.sddm = {
+ createHome = true;
+ home = "/var/lib/sddm";
+ group = "sddm";
+ uid = config.ids.uids.sddm;
+ };
+
+ environment.etc."sddm.conf".source = cfgFile;
+
+ users.extraGroups.sddm.gid = config.ids.gids.sddm;
+
+ };
+}
diff --git a/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix
index 9ee4e0dc7cb..c7fbfa85e33 100644
--- a/nixos/modules/services/x11/display-managers/slim.nix
+++ b/nixos/modules/services/x11/display-managers/slim.nix
@@ -19,6 +19,7 @@ let
reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
${optionalString (cfg.defaultUser != null) ("default_user " + cfg.defaultUser)}
${optionalString cfg.autoLogin "auto_login yes"}
+ ${cfg.extraConfig}
'';
# Unpack the SLiM theme, or use the default.
@@ -89,6 +90,15 @@ in
'';
};
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra configuration options for SLiM login manager. Do not
+ add options that can be configured directly.
+ '';
+ };
+
};
};
diff --git a/nixos/modules/services/x11/hardware/multitouch.nix b/nixos/modules/services/x11/hardware/multitouch.nix
index 6e6e88e6721..f8386b5e333 100644
--- a/nixos/modules/services/x11/hardware/multitouch.nix
+++ b/nixos/modules/services/x11/hardware/multitouch.nix
@@ -2,9 +2,15 @@
with lib;
-let cfg = config.services.xserver.multitouch; in
-
-{
+let cfg = config.services.xserver.multitouch;
+ disabledTapConfig = ''
+ Option "MaxTapTime" "0"
+ Option "MaxTapMove" "0"
+ Option "TapButton1" "0"
+ Option "TapButton2" "0"
+ Option "TapButton3" "0"
+ '';
+in {
options = {
@@ -30,6 +36,33 @@ let cfg = config.services.xserver.multitouch; in
description = "Whether to ignore touches detected as being the palm (i.e when typing)";
};
+ tapButtons = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = "Whether to enable tap buttons.";
+ };
+
+ buttonsMap = mkOption {
+ type = types.listOf types.int;
+ default = [3 2 0];
+ example = [1 3 2];
+ description = "Remap touchpad buttons.";
+ apply = map toString;
+ };
+
+ additionalOptions = mkOption {
+ type = types.str;
+ default = "";
+ example = ''
+ Option "ScaleDistance" "50"
+ Option "RotateDistance" "60"
+ '';
+ description = ''
+ Additional options for mtrack touchpad driver.
+ '';
+ };
+
};
};
@@ -46,12 +79,17 @@ let cfg = config.services.xserver.multitouch; in
Identifier "Touchpads"
Driver "mtrack"
Option "IgnorePalm" "${if cfg.ignorePalm then "true" else "false"}"
+ Option "ClickFinger1" "${builtins.elemAt cfg.buttonsMap 0}"
+ Option "ClickFinger2" "${builtins.elemAt cfg.buttonsMap 1}"
+ Option "ClickFinger3" "${builtins.elemAt cfg.buttonsMap 2}"
+ ${optionalString (!cfg.tapButtons) disabledTapConfig}
${optionalString cfg.invertScroll ''
Option "ScrollUpButton" "5"
Option "ScrollDownButton" "4"
Option "ScrollLeftButton" "7"
Option "ScrollRightButton" "6"
''}
+ ${cfg.additionalOptions}
EndSection
'';
diff --git a/nixos/modules/services/x11/hardware/synaptics.nix b/nixos/modules/services/x11/hardware/synaptics.nix
index f5b394b6d98..9e44ce811c3 100644
--- a/nixos/modules/services/x11/hardware/synaptics.nix
+++ b/nixos/modules/services/x11/hardware/synaptics.nix
@@ -7,9 +7,9 @@ let cfg = config.services.xserver.synaptics;
enabledTapConfig = ''
Option "MaxTapTime" "180"
Option "MaxTapMove" "220"
- Option "TapButton1" "${builtins.elemAt cfg.buttonsMap 0}"
- Option "TapButton2" "${builtins.elemAt cfg.buttonsMap 1}"
- Option "TapButton3" "${builtins.elemAt cfg.buttonsMap 2}"
+ Option "TapButton1" "${builtins.elemAt cfg.fingersMap 0}"
+ Option "TapButton2" "${builtins.elemAt cfg.fingersMap 1}"
+ Option "TapButton3" "${builtins.elemAt cfg.fingersMap 2}"
'';
disabledTapConfig = ''
Option "MaxTapTime" "0"
@@ -25,12 +25,14 @@ in {
services.xserver.synaptics = {
enable = mkOption {
+ type = types.bool;
default = false;
example = true;
description = "Whether to enable touchpad support.";
};
dev = mkOption {
+ type = types.nullOr types.str;
default = null;
example = "/dev/input/event0";
description =
@@ -59,41 +61,56 @@ in {
};
twoFingerScroll = mkOption {
+ type = types.bool;
default = false;
description = "Whether to enable two-finger drag-scrolling.";
};
vertEdgeScroll = mkOption {
+ type = types.bool;
default = ! cfg.twoFingerScroll;
description = "Whether to enable vertical edge drag-scrolling.";
};
tapButtons = mkOption {
+ type = types.bool;
default = true;
example = false;
description = "Whether to enable tap buttons.";
};
buttonsMap = mkOption {
+ type = types.listOf types.int;
default = [1 2 3];
example = [1 3 2];
description = "Remap touchpad buttons.";
apply = map toString;
};
+ fingersMap = mkOption {
+ type = types.listOf types.int;
+ default = [1 2 3];
+ example = [1 3 2];
+ description = "Remap several-fingers taps.";
+ apply = map toString;
+ };
+
palmDetect = mkOption {
+ type = types.bool;
default = false;
example = true;
description = "Whether to enable palm detection (hardware support required)";
};
horizontalScroll = mkOption {
+ type = types.bool;
default = true;
example = false;
description = "Whether to enable horizontal scrolling (on touchpad)";
};
additionalOptions = mkOption {
+ type = types.str;
default = "";
example = ''
Option "RTCornerButton" "2"
diff --git a/nixos/modules/services/x11/unclutter.nix b/nixos/modules/services/x11/unclutter.nix
new file mode 100644
index 00000000000..556d9e187fd
--- /dev/null
+++ b/nixos/modules/services/x11/unclutter.nix
@@ -0,0 +1,33 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let cfg = config.services.unclutter;
+in {
+ options = {
+ services.unclutter.enable = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Enable unclutter to hide your mouse cursor when inactive";
+ };
+
+ services.unclutter.arguments = mkOption {
+ description = "Arguments to pass to unclutter command";
+ default = "-idle 1";
+ type = types.uniq types.string;
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.services.unclutter = {
+ description = "unclutter";
+ requires = [ "display-manager.service" ];
+ after = [ "display-manager.service" ];
+ wantedBy = [ "graphical.target" ];
+ serviceConfig.ExecStart = ''
+ ${pkgs.unclutter}/bin/unclutter ${cfg.arguments}
+ '';
+ environment = { DISPLAY = ":0"; };
+ serviceConfig.Restart = "always";
+ };
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/afterstep.nix b/nixos/modules/services/x11/window-managers/afterstep.nix
new file mode 100644
index 00000000000..395dabb86b5
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/afterstep.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.afterstep;
+in
+{
+ ###### interface
+ options = {
+ services.xserver.windowManager.afterstep.enable = mkOption {
+ default = false;
+ description = "Enable the Afterstep window manager.";
+ };
+ };
+
+ ###### implementation
+ config = mkIf cfg.enable {
+ services.xserver.windowManager.session = singleton {
+ name = "afterstep";
+ start = ''
+ ${pkgs.afterstep}/bin/afterstep &
+ waitPID=$!
+ '';
+ };
+ environment.systemPackages = [ pkgs.afterstep ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/awesome.nix b/nixos/modules/services/x11/window-managers/awesome.nix
index 9b2f042a87a..455b3568499 100644
--- a/nixos/modules/services/x11/window-managers/awesome.nix
+++ b/nixos/modules/services/x11/window-managers/awesome.nix
@@ -5,6 +5,7 @@ with lib;
let
cfg = config.services.xserver.windowManager.awesome;
+ awesome = cfg.package;
in
@@ -14,9 +15,24 @@ in
options = {
- services.xserver.windowManager.awesome.enable = mkOption {
- default = false;
- description = "Enable the Awesome window manager.";
+ services.xserver.windowManager.awesome = {
+
+ enable = mkEnableOption "Awesome window manager";
+
+ luaModules = mkOption {
+ default = [];
+ type = types.listOf types.package;
+ description = "List of lua packages available for being used in the Awesome configuration.";
+ example = literalExample "[ luaPackages.oocairo ]";
+ };
+
+ package = mkOption {
+ default = null;
+ type = types.nullOr types.package;
+ description = "Package to use for running the Awesome WM.";
+ apply = pkg: if pkg == null then pkgs.awesome else pkg;
+ };
+
};
};
@@ -30,12 +46,17 @@ in
{ name = "awesome";
start =
''
- ${pkgs.awesome}/bin/awesome &
+ ${concatMapStrings (pkg: ''
+ export LUA_CPATH=$LUA_CPATH''${LUA_CPATH:+;}${pkg}/lib/lua/${awesome.lua.luaversion}/?.so
+ export LUA_PATH=$LUA_PATH''${LUA_PATH:+;}${pkg}/lib/lua/${awesome.lua.luaversion}/?.lua
+ '') cfg.luaModules}
+
+ ${awesome}/bin/awesome &
waitPID=$!
'';
};
- environment.systemPackages = [ pkgs.awesome ];
+ environment.systemPackages = [ awesome ];
};
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index 45a4e947e0a..097e4fe70d5 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -7,18 +7,24 @@ let
in
{
- imports =
- [ ./compiz.nix
- ./openbox.nix
- ./metacity.nix
- ./none.nix
- ./twm.nix
- ./wmii.nix
- ./xmonad.nix
- ./i3.nix
- ./herbstluftwm.nix
- ./bspwm.nix
- ];
+ imports = [
+ ./afterstep.nix
+ ./bspwm.nix
+ ./compiz.nix
+ ./fluxbox.nix
+ ./herbstluftwm.nix
+ ./i3.nix
+ ./metacity.nix
+ ./openbox.nix
+ ./ratpoison.nix
+ ./sawfish.nix
+ ./stumpwm.nix
+ ./spectrwm.nix
+ ./twm.nix
+ ./windowmaker.nix
+ ./wmii.nix
+ ./xmonad.nix
+ ./none.nix ];
options = {
diff --git a/nixos/modules/services/x11/window-managers/ratpoison.nix b/nixos/modules/services/x11/window-managers/ratpoison.nix
new file mode 100644
index 00000000000..c203c35cd1b
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/ratpoison.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.ratpoison;
+in
+{
+ ###### interface
+ options = {
+ services.xserver.windowManager.ratpoison.enable = mkOption {
+ default = false;
+ description = "Enable the Ratpoison window manager.";
+ };
+ };
+
+ ###### implementation
+ config = mkIf cfg.enable {
+ services.xserver.windowManager.session = singleton {
+ name = "ratpoison";
+ start = ''
+ ${pkgs.ratpoison}/bin/ratpoison &
+ waitPID=$!
+ '';
+ };
+ environment.systemPackages = [ pkgs.ratpoison ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/sawfish.nix b/nixos/modules/services/x11/window-managers/sawfish.nix
new file mode 100644
index 00000000000..74a11926020
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/sawfish.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.sawfish;
+in
+{
+ ###### interface
+ options = {
+ services.xserver.windowManager.sawfish.enable = mkOption {
+ default = false;
+ description = "Enable the Sawfish window manager.";
+ };
+ };
+
+ ###### implementation
+ config = mkIf cfg.enable {
+ services.xserver.windowManager.session = singleton {
+ name = "sawfish";
+ start = ''
+ ${pkgs.sawfish}/bin/sawfish &
+ waitPID=$!
+ '';
+ };
+ environment.systemPackages = [ pkgs.sawfish ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/spectrwm.nix b/nixos/modules/services/x11/window-managers/spectrwm.nix
new file mode 100644
index 00000000000..5db6b41ba8f
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/spectrwm.nix
@@ -0,0 +1,33 @@
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.spectrwm;
+in
+
+{
+ options = {
+ services.xserver.windowManager.spectrwm = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the spectrwm window manager.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.xserver.windowManager = {
+ session = [{
+ name = "spectrwm";
+ start = ''
+ ${pkgs.spectrwm}/bin/spectrwm &
+ waitPID=$!
+ '';
+ }];
+ };
+ environment.systemPackages = [ pkgs.spectrwm ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/stumpwm.nix b/nixos/modules/services/x11/window-managers/stumpwm.nix
new file mode 100644
index 00000000000..a876f13fd21
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/stumpwm.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.stumpwm;
+in
+
+{
+ options = {
+ services.xserver.windowManager.stumpwm = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = "Enable the stumpwm tiling window manager.";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ services.xserver.windowManager.session = singleton {
+ name = "stumpwm";
+ start = "
+ ${pkgs.stumpwm}/bin/stumpwm
+ ";
+ };
+ environment.systemPackages = [ pkgs.stumpwm ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/windowmaker.nix b/nixos/modules/services/x11/window-managers/windowmaker.nix
new file mode 100644
index 00000000000..27cedb7da0c
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/windowmaker.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.xserver.windowManager.windowmaker;
+in
+{
+ ###### interface
+ options = {
+ services.xserver.windowManager.windowmaker.enable = mkOption {
+ default = false;
+ description = "Enable the Windowmaker window manager.";
+ };
+ };
+
+ ###### implementation
+ config = mkIf cfg.enable {
+ services.xserver.windowManager.session = singleton {
+ name = "windowmaker";
+ start = ''
+ ${pkgs.windowmaker}/bin/wmaker &
+ waitPID=$!
+ '';
+ };
+ environment.systemPackages = [ pkgs.windowmaker ];
+ };
+}
diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix
index 74acfc21975..c922ca7848d 100644
--- a/nixos/modules/services/x11/window-managers/xmonad.nix
+++ b/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -3,11 +3,12 @@
let
inherit (lib) mkOption mkIf optionals literalExample;
cfg = config.services.xserver.windowManager.xmonad;
- xmonadEnv = cfg.haskellPackages.ghcWithPackages(self: [
- self.xmonad
- ] ++ optionals cfg.enableContribAndExtras [ self.xmonadContrib self.xmonadExtras]
- ++ optionals (cfg.extraPackages != null) (cfg.extraPackages self));
- xmessage = pkgs.xlibs.xmessage;
+ xmonad = pkgs.xmonad-with-packages.override {
+ ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
+ packages = self: cfg.extraPackages self ++
+ optionals cfg.enableContribAndExtras
+ [ self.xmonad-contrib self.xmonad-extras ];
+ };
in
{
options = {
@@ -19,9 +20,9 @@ in
};
haskellPackages = mkOption {
- default = pkgs.haskellPackages;
- defaultText = "pkgs.haskellPackages";
- example = literalExample "pkgs.haskellPackages_ghc701";
+ default = pkgs.haskellngPackages;
+ defaultText = "pkgs.haskellngPackages";
+ example = literalExample "pkgs.haskell-ng.packages.ghc784";
description = ''
haskellPackages used to build Xmonad and other packages.
This can be used to change the GHC version used to build
@@ -31,17 +32,17 @@ in
};
extraPackages = mkOption {
- default = null;
+ default = self: [];
example = literalExample ''
haskellPackages: [
- haskellPackages.xmonadContrib
- haskellPackages.monadLogger
+ haskellPackages.xmonad-contrib
+ haskellPackages.monad-logger
]
'';
description = ''
Extra packages available to ghc when rebuilding Xmonad. The
value must be a function which receives the attrset defined
- in haskellpackages as the sole argument.
+ in haskellPackages as the sole argument.
'';
};
@@ -58,12 +59,12 @@ in
session = [{
name = "xmonad";
start = ''
- XMONAD_GHC=${xmonadEnv}/bin/ghc XMONAD_XMESSAGE=${xmessage}/bin/xmessage xmonad &
+ ${xmonad}/bin/xmonad &
waitPID=$!
'';
}];
};
- environment.systemPackages = [ cfg.haskellPackages.xmonad ];
+ environment.systemPackages = [ xmonad ];
};
}
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix
index 21eaf6bb6b7..64e0d4d8050 100644
--- a/nixos/modules/services/x11/xserver.nix
+++ b/nixos/modules/services/x11/xserver.nix
@@ -13,7 +13,6 @@ let
# Map video driver names to driver packages. FIXME: move into card-specific modules.
knownVideoDrivers = {
- ati_unfree = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; };
nouveau = { modules = [ pkgs.xf86_video_nouveau ]; };
unichrome = { modules = [ pkgs.xorgVideoUnichrome ]; };
virtualbox = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
@@ -400,8 +399,8 @@ in
services.xserver.drivers = flip concatMap cfg.videoDrivers (name:
let driver =
attrByPath [name]
- (if (hasAttr ("xf86video" + name) xorg)
- then { modules = [(getAttr ("xf86video" + name) xorg) ]; }
+ (if xorg ? ${"xf86video" + name}
+ then { modules = [xorg.${"xf86video" + name}]; }
else null)
knownVideoDrivers;
in optional (driver != null) ({ inherit name; driverName = name; } // driver));
@@ -444,8 +443,7 @@ in
pkgs.xterm
pkgs.xdg_utils
]
- ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh
- ++ optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11;
+ ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh;
environment.pathsToLink =
[ "/etc/xdg" "/share/xdg" "/share/applications" "/share/icons" "/share/pixmaps" ];
@@ -460,13 +458,11 @@ in
restartIfChanged = false;
environment =
- { FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; # !!! cleanup
+ {
XKB_BINDIR = "${xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
LD_LIBRARY_PATH = concatStringsSep ":" (
[ "${xorg.libX11}/lib" "${xorg.libXext}/lib" ]
- ++ optionals (elem "ati_unfree" cfg.videoDrivers)
- [ "${kernelPackages.ati_drivers_x11}/lib" "${kernelPackages.ati_drivers_x11}/X11R6/lib64/modules/linux" ]
++ concatLists (catAttrs "libPath" cfg.drivers));
} // cfg.displayManager.job.environment;
@@ -487,8 +483,6 @@ in
services.xserver.displayManager.xserverArgs =
[ "-ac"
- "-logverbose"
- "-verbose"
"-terminate"
"-logfile" "/var/log/X.${toString cfg.display}.log"
"-config ${configFile}"
diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl
index 12012698efe..7aa4b12a654 100644
--- a/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/nixos/modules/system/activation/switch-to-configuration.pl
@@ -9,19 +9,21 @@ use Cwd 'abs_path';
my $out = "@out@";
+# To be robust against interruption, record what units need to be started etc.
my $startListFile = "/run/systemd/start-list";
my $restartListFile = "/run/systemd/restart-list";
my $reloadListFile = "/run/systemd/reload-list";
my $action = shift @ARGV;
-if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test")) {
+if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
print STDERR < 1 }, "$unit\n") if $action ne "dry-activate";
+}
+
# As a fingerprint for determining whether a unit has changed, we use
# its absolute path. If it has an override file, we append *its*
# absolute path as well.
@@ -124,9 +129,20 @@ sub fingerprintUnit {
return abs_path($s) . (-f "${s}.d/overrides.conf" ? " " . abs_path "${s}.d/overrides.conf" : "");
}
-# Stop all services that no longer exist or have changed in the new
-# configuration.
-my (@unitsToStop, @unitsToSkip);
+# Figure out what units need to be stopped, started, restarted or reloaded.
+my (%unitsToStop, %unitsToSkip, %unitsToStart, %unitsToRestart, %unitsToReload);
+
+my %unitsToFilter; # units not shown
+
+$unitsToStart{$_} = 1 foreach
+ split('\n', read_file($startListFile, err_mode => 'quiet') // "");
+
+$unitsToRestart{$_} = 1 foreach
+ split('\n', read_file($restartListFile, err_mode => 'quiet') // "");
+
+$unitsToReload{$_} = 1 foreach
+ split '\n', read_file($reloadListFile, err_mode => 'quiet') // "";
+
my $activePrev = getActiveUnits;
while (my ($unit, $state) = each %{$activePrev}) {
my $baseUnit = $unit;
@@ -141,7 +157,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
- push @unitsToStop, $unit;
+ $unitsToStop{$unit} = 1;
}
elsif ($unit =~ /\.target$/) {
@@ -155,7 +171,10 @@ while (my ($unit, $state) = each %{$activePrev}) {
# should not be the case. Just ignore it.
if ($unit ne "suspend.target" && $unit ne "hibernate.target" && $unit ne "hybrid-sleep.target") {
unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no")) {
- write_file($startListFile, { append => 1 }, "$unit\n");
+ $unitsToStart{$unit} = 1;
+ recordUnit($startListFile, $unit);
+ # Don't spam the user with target units that always get started.
+ $unitsToFilter{$unit} = 1;
}
}
@@ -171,7 +190,7 @@ while (my ($unit, $state) = each %{$activePrev}) {
# (unless there is a PartOf dependency), so this is just a
# bookkeeping thing to get systemd to do the right thing.
if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "no")) {
- push @unitsToStop, $unit;
+ $unitsToStop{$unit} = 1;
}
}
@@ -180,16 +199,18 @@ while (my ($unit, $state) = each %{$activePrev}) {
# Do nothing. These cannot be restarted directly.
} elsif ($unit =~ /\.mount$/) {
# Reload the changed mount unit to force a remount.
- write_file($reloadListFile, { append => 1 }, "$unit\n");
- } elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/) {
+ $unitsToReload{$unit} = 1;
+ recordUnit($reloadListFile, $unit);
+ } elsif ($unit =~ /\.socket$/ || $unit =~ /\.path$/ || $unit =~ /\.slice$/) {
# FIXME: do something?
} else {
my $unitInfo = parseUnit($newUnitFile);
if (boolIsTrue($unitInfo->{'X-ReloadIfChanged'} // "no")) {
- write_file($reloadListFile, { append => 1 }, "$unit\n");
+ $unitsToReload{$unit} = 1;
+ recordUnit($reloadListFile, $unit);
}
elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes") || boolIsTrue($unitInfo->{'RefuseManualStop'} // "no") ) {
- push @unitsToSkip, $unit;
+ $unitsToSkip{$unit} = 1;
} else {
# If this unit is socket-activated, then stop the
# socket unit(s) as well, and restart the
@@ -202,8 +223,9 @@ while (my ($unit, $state) = each %{$activePrev}) {
}
foreach my $socket (@sockets) {
if (defined $activePrev->{$socket}) {
- push @unitsToStop, $socket;
- write_file($startListFile, { append => 1 }, "$socket\n");
+ $unitsToStop{$unit} = 1;
+ $unitsToStart{$unit} = 1;
+ recordUnit($startListFile, $socket);
$socketActivated = 1;
}
}
@@ -213,7 +235,8 @@ while (my ($unit, $state) = each %{$activePrev}) {
# This unit should be restarted instead of
# stopped and started.
- write_file($restartListFile, { append => 1 }, "$unit\n");
+ $unitsToRestart{$unit} = 1;
+ recordUnit($restartListFile, $unit);
} else {
@@ -222,10 +245,11 @@ while (my ($unit, $state) = each %{$activePrev}) {
# We write this to a file to ensure that the
# service gets restarted if we're interrupted.
if (!$socketActivated) {
- write_file($startListFile, { append => 1 }, "$unit\n");
+ $unitsToStart{$unit} = 1;
+ recordUnit($startListFile, $unit);
}
- push @unitsToStop, $unit;
+ $unitsToStop{$unit} = 1;
}
}
@@ -268,14 +292,16 @@ foreach my $mountPoint (keys %$prevFss) {
my $unit = pathToUnitName($mountPoint) . ".mount";
if (!defined $new) {
# Filesystem entry disappeared, so unmount it.
- push @unitsToStop, $unit;
+ $unitsToStop{$unit} = 1;
} elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
# Filesystem type or device changed, so unmount and mount it.
- write_file($startListFile, { append => 1 }, "$unit\n");
- push @unitsToStop, $unit;
+ $unitsToStop{$unit} = 1;
+ $unitsToStart{$unit} = 1;
+ recordUnit($startListFile, $unit);
} elsif ($prev->{options} ne $new->{options}) {
# Mount options changes, so remount it.
- write_file($reloadListFile, { append => 1 }, "$unit\n");
+ $unitsToReload{$unit} = 1;
+ recordUnit($reloadListFile, $unit);
}
}
@@ -294,14 +320,51 @@ foreach my $device (keys %$prevSwaps) {
# FIXME: update swap options (i.e. its priority).
}
-if (scalar @unitsToStop > 0) {
- @unitsToStop = unique(@unitsToStop);
- print STDERR "stopping the following units: ", join(", ", sort(@unitsToStop)), "\n";
- system("systemctl", "stop", "--", @unitsToStop); # FIXME: ignore errors?
+
+# Should we have systemd re-exec itself?
+my $restartSystemd = abs_path("/proc/1/exe") ne abs_path("@systemd@/lib/systemd/systemd");
+
+
+sub filterUnits {
+ my ($units) = @_;
+ my @res;
+ foreach my $unit (sort(keys %{$units})) {
+ push @res, $unit if !defined $unitsToFilter{$unit};
+ }
+ return @res;
}
-print STDERR "NOT restarting the following units: ", join(", ", sort(@unitsToSkip)), "\n"
- if scalar @unitsToSkip > 0;
+my @unitsToStopFiltered = filterUnits(\%unitsToStop);
+my @unitsToStartFiltered = filterUnits(\%unitsToStart);
+
+
+# Show dry-run actions.
+if ($action eq "dry-activate") {
+ print STDERR "would stop the following units: ", join(", ", @unitsToStopFiltered), "\n"
+ if scalar @unitsToStopFiltered > 0;
+ print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
+ if scalar(keys %unitsToSkip) > 0;
+ print STDERR "would restart systemd\n" if $restartSystemd;
+ print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
+ if scalar(keys %unitsToRestart) > 0;
+ print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
+ if scalar @unitsToStartFiltered;
+ print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
+ if scalar(keys %unitsToReload) > 0;
+ exit 0;
+}
+
+
+syslog(LOG_NOTICE, "switching to system configuration $out");
+
+if (scalar (keys %unitsToStop) > 0) {
+ print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
+ if scalar @unitsToStopFiltered;
+ system("systemctl", "stop", "--", sort(keys %unitsToStop)); # FIXME: ignore errors?
+}
+
+print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
+ if scalar(keys %unitsToSkip) > 0;
# Activate the new configuration (i.e., update /etc, make accounts,
# and so on).
@@ -310,7 +373,7 @@ print STDERR "activating the configuration...\n";
system("$out/activate", "$out") == 0 or $res = 2;
# Restart systemd if necessary.
-if (abs_path("/proc/1/exe") ne abs_path("@systemd@/lib/systemd/systemd")) {
+if ($restartSystemd) {
print STDERR "restarting systemd...\n";
system("@systemd@/bin/systemctl", "daemon-reexec") == 0 or $res = 2;
}
@@ -321,12 +384,19 @@ system("@systemd@/bin/systemctl", "reset-failed");
# Make systemd reload its units.
system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
+# Reload units that need it. This includes remounting changed mount
+# units.
+if (scalar(keys %unitsToReload) > 0) {
+ print STDERR "reloading the following units: ", join(", ", sort(keys %unitsToReload)), "\n";
+ system("@systemd@/bin/systemctl", "reload", "--", sort(keys %unitsToReload)) == 0 or $res = 4;
+ unlink($reloadListFile);
+}
+
# Restart changed services (those that have to be restarted rather
# than stopped and started).
-my @restart = unique(split('\n', read_file($restartListFile, err_mode => 'quiet') // ""));
-if (scalar @restart > 0) {
- print STDERR "restarting the following units: ", join(", ", sort(@restart)), "\n";
- system("@systemd@/bin/systemctl", "restart", "--", @restart) == 0 or $res = 4;
+if (scalar(keys %unitsToRestart) > 0) {
+ print STDERR "restarting the following units: ", join(", ", sort(keys %unitsToRestart)), "\n";
+ system("@systemd@/bin/systemctl", "restart", "--", sort(keys %unitsToRestart)) == 0 or $res = 4;
unlink($restartListFile);
}
@@ -336,22 +406,11 @@ if (scalar @restart > 0) {
# that are symlinks to other units. We shouldn't start both at the
# same time because we'll get a "Failed to add path to set" error from
# systemd.
-my @start = unique("default.target", "timers.target", "sockets.target", split('\n', read_file($startListFile, err_mode => 'quiet') // ""));
-print STDERR "starting the following units: ", join(", ", sort(@start)), "\n";
-system("@systemd@/bin/systemctl", "start", "--", @start) == 0 or $res = 4;
+print STDERR "starting the following units: ", join(", ", @unitsToStartFiltered), "\n"
+ if scalar @unitsToStartFiltered;
+system("@systemd@/bin/systemctl", "start", "--", sort(keys %unitsToStart)) == 0 or $res = 4;
unlink($startListFile);
-# Reload units that need it. This includes remounting changed mount
-# units.
-my @reload = unique(split '\n', read_file($reloadListFile, err_mode => 'quiet') // "");
-if (scalar @reload > 0) {
- print STDERR "reloading the following units: ", join(", ", sort(@reload)), "\n";
- system("@systemd@/bin/systemctl", "reload", "--", @reload) == 0 or $res = 4;
- unlink($reloadListFile);
-}
-
-# Signal dbus to reload its configuration.
-system("@systemd@/bin/systemctl", "reload", "dbus.service");
# Print failed and new units.
my (@failed, @new, @restarting);
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 62999dceee3..d7a1e205b4d 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -88,7 +88,7 @@ let
failed = map (x: x.message) (filter (x: !x.assertion) config.assertions);
- showWarnings = res: fold (w: x: builtins.trace "^[[1;31mwarning: ${w}^[[0m" x) res config.warnings;
+ showWarnings = res: fold (w: x: builtins.trace "[1;31mwarning: ${w}[0m" x) res config.warnings;
# Putting it all together. This builds a store path containing
# symlinks to the various parts of the built configuration (the
@@ -147,7 +147,7 @@ in
default = [];
description = ''
Additional configurations to build based on the current
- configuration which is has a lower priority.
+ configuration which then has a lower priority.
'';
};
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index 79b173a6ead..0cae9cb844c 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -193,8 +193,9 @@ in
"ohci_hcd"
"ohci_pci"
"xhci_hcd"
+ "xhci_pci"
"usbhid"
- "hid_generic"
+ "hid_generic" "hid_lenovo"
"hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat"
# Unix domain sockets (needed by udev).
diff --git a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
index 4b5e84f53c1..6153578612c 100644
--- a/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
+++ b/nixos/modules/system/boot/loader/generations-dir/generations-dir.nix
@@ -24,6 +24,7 @@ in
enable = mkOption {
default = false;
+ type = types.bool;
description = ''
Whether to create symlinks to the system generations under
/boot . When enabled,
@@ -42,6 +43,7 @@ in
copyKernels = mkOption {
default = false;
+ type = types.bool;
description = "
Whether copy the necessary boot files into /boot, so
/nix/store is not needed by the boot loader.
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix
index bc9a155ac95..585c8854fee 100644
--- a/nixos/modules/system/boot/loader/grub/grub.nix
+++ b/nixos/modules/system/boot/loader/grub/grub.nix
@@ -6,8 +6,11 @@ let
cfg = config.boot.loader.grub;
+ efi = config.boot.loader.efi;
+
realGrub = if cfg.version == 1 then pkgs.grub
- else pkgs.grub2.override { zfsSupport = cfg.zfsSupport; };
+ else if cfg.zfsSupport then pkgs.grub2.override { zfsSupport = true; }
+ else pkgs.grub2;
grub =
# Don't include GRUB if we're only generating a GRUB menu (e.g.,
@@ -16,21 +19,31 @@ let
then null
else realGrub;
+ grubEfi =
+ # EFI version of Grub v2
+ if (cfg.devices != ["nodev"]) && cfg.efiSupport && (cfg.version == 2)
+ then realGrub.override { efiSupport = cfg.efiSupport; }
+ else null;
+
f = x: if x == null then "" else "" + x;
grubConfig = pkgs.writeText "grub-config.xml" (builtins.toXML
{ splashImage = f config.boot.loader.grub.splashImage;
grub = f grub;
+ grubTarget = f (grub.grubTarget or "");
shell = "${pkgs.stdenv.shell}";
fullVersion = (builtins.parseDrvName realGrub.name).version;
+ grubEfi = f grubEfi;
+ grubTargetEfi = if cfg.efiSupport && (cfg.version == 2) then f (grubEfi.grubTarget or "") else "";
+ inherit (efi) efiSysMountPoint canTouchEfiVariables;
inherit (cfg)
version extraConfig extraPerEntryConfig extraEntries
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels timeout
- default devices fsIdentifier;
- path = (makeSearchPath "bin" [
+ default devices fsIdentifier efiSupport;
+ path = (makeSearchPath "bin" ([
pkgs.coreutils pkgs.gnused pkgs.gnugrep pkgs.findutils pkgs.diffutils pkgs.btrfsProgs
- pkgs.utillinux
- ]) + ":" + (makeSearchPath "sbin" [
+ pkgs.utillinux ] ++ (if cfg.efiSupport && (cfg.version == 2) then [pkgs.efibootmgr ] else [])
+ )) + ":" + (makeSearchPath "sbin" [
pkgs.mdadm pkgs.utillinux
]);
});
@@ -166,6 +179,7 @@ in
};
splashImage = mkOption {
+ type = types.nullOr types.path;
example = literalExample "./my-background.png";
description = ''
Background image used for GRUB. It must be a 640x480,
@@ -196,7 +210,7 @@ in
};
timeout = mkOption {
- default = 5;
+ default = if (config.boot.loader.timeout != null) then config.boot.loader.timeout else -1;
type = types.int;
description = ''
Timeout (in seconds) until GRUB boots the default menu item.
@@ -231,6 +245,27 @@ in
type = types.bool;
description = ''
Whether grub should be build against libzfs.
+ ZFS support is only available for GRUB v2.
+ This option is ignored for GRUB v1.
+ '';
+ };
+
+ efiSupport = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether grub should be build with EFI support.
+ EFI support is only available for GRUB v2.
+ This option is ignored for GRUB v1.
+ '';
+ };
+
+ enableCryptodisk = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Enable support for encrypted partitions. Grub should automatically
+ unlock the correct encrypted partition and look for filesystems.
'';
};
@@ -260,7 +295,8 @@ in
if cfg.devices == [] then
throw "You must set the option ‘boot.loader.grub.device’ to make the system bootable."
else
- "PERL5LIB=${makePerlPath [ pkgs.perlPackages.XMLLibXML pkgs.perlPackages.XMLSAX ]} " +
+ "PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])} " +
+ (if cfg.enableCryptodisk then "GRUB_ENABLE_CRYPTODISK=y " else "") +
"${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig}";
system.build.grub = grub;
@@ -277,7 +313,11 @@ in
'') config.boot.loader.grub.extraFiles);
assertions = [{ assertion = !cfg.zfsSupport || cfg.version == 2;
- message = "Only grub version 2 provides zfs support";}];
+ message = "Only grub version 2 provides zfs support";}]
+ ++ flip map cfg.devices (dev: {
+ assertion = dev == "nodev" || hasPrefix "/" dev;
+ message = "Grub devices must be absolute paths, not ${dev}";
+ });
})
diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl
index d8ee8b50097..2ef1fca1983 100644
--- a/nixos/modules/system/boot/loader/grub/install-grub.pl
+++ b/nixos/modules/system/boot/loader/grub/install-grub.pl
@@ -6,6 +6,8 @@ use File::Basename;
use File::Path;
use File::stat;
use File::Copy;
+use File::Slurp;
+require List::Compare;
use POSIX;
use Cwd;
@@ -38,6 +40,7 @@ sub runCommand {
my $grub = get("grub");
my $grubVersion = int(get("version"));
+my $grubTarget = get("grubTarget");
my $extraConfig = get("extraConfig");
my $extraPrepareConfig = get("extraPrepareConfig");
my $extraPerEntryConfig = get("extraPerEntryConfig");
@@ -49,6 +52,10 @@ my $copyKernels = get("copyKernels") eq "true";
my $timeout = int(get("timeout"));
my $defaultEntry = int(get("default"));
my $fsIdentifier = get("fsIdentifier");
+my $grubEfi = get("grubEfi");
+my $grubTargetEfi = get("grubTargetEfi");
+my $canTouchEfiVariables = get("canTouchEfiVariables");
+my $efiSysMountPoint = get("efiSysMountPoint");
$ENV{'PATH'} = get("path");
die "unsupported GRUB version\n" if $grubVersion != 1 && $grubVersion != 2;
@@ -70,14 +77,50 @@ struct(Fs => {
type => '$',
mount => '$',
});
+sub PathInMount {
+ my ($path, $mount) = @_;
+ my @splitMount = split /\//, $mount;
+ my @splitPath = split /\//, $path;
+ if ($#splitPath < $#splitMount) {
+ return 0;
+ }
+ for (my $i = 0; $i <= $#splitMount; $i++) {
+ if ($splitMount[$i] ne $splitPath[$i]) {
+ return 0;
+ }
+ }
+ return 1;
+}
sub GetFs {
my ($dir) = @_;
- my ($status, @dfOut) = runCommand("df -T $dir");
- if ($status != 0 || $#dfOut != 1) {
- die "Failed to retrieve output about $dir from `df`";
+ my $bestFs = Fs->new(device => "", type => "", mount => "");
+ foreach my $fs (read_file("/proc/self/mountinfo")) {
+ chomp $fs;
+ my @fields = split / /, $fs;
+ my $mountPoint = $fields[4];
+ next unless -d $mountPoint;
+ my @mountOptions = split /,/, $fields[5];
+
+ # Skip the optional fields.
+ my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
+ my $fsType = $fields[$n];
+ my $device = $fields[$n + 1];
+ my @superOptions = split /,/, $fields[$n + 2];
+
+ # Skip the read-only bind-mount on /nix/store.
+ next if $mountPoint eq "/nix/store" && (grep { $_ eq "rw" } @superOptions) && (grep { $_ eq "ro" } @mountOptions);
+ # Skip mount point generated by systemd-efi-boot-generator?
+ next if $fsType eq "autofs";
+
+ # Ensure this matches the intended directory
+ next unless PathInMount($dir, $mountPoint);
+
+ # Is it better than our current match?
+ if (length($mountPoint) > length($bestFs->mount)) {
+ $bestFs = Fs->new(device => $device, type => $fsType, mount => $mountPoint);
+ }
}
- my @boot = split(/[ \n\t]+/, $dfOut[1]);
- return Fs->new(device => $boot[0], type => $boot[1], mount => $boot[6]);
+ return $bestFs;
}
struct (Grub => {
path => '$',
@@ -122,7 +165,7 @@ sub GrubFs {
# Based on the type pull in the identifier from the system
my ($status, @devInfo) = runCommand("blkid -o export @{[$fs->device]}");
if ($status != 0) {
- die "Failed to get blkid info for @{[$fs->device]}";
+ die "Failed to get blkid info for @{[$fs->mount]} on @{[$fs->device]}";
}
my @matches = join("", @devInfo) =~ m/@{[uc $fsIdentifier]}=([^\n]*)/;
if ($#matches != 0) {
@@ -133,15 +176,25 @@ sub GrubFs {
# BTRFS is a special case in that we need to fix the referrenced path based on subvolumes
if ($fs->type eq 'btrfs') {
- my ($status, @info) = runCommand("btrfs subvol show @{[$fs->mount]}");
+ my ($status, @id_info) = runCommand("btrfs subvol show @{[$fs->mount]}");
if ($status != 0) {
- die "Failed to retreive subvolume info for @{[$fs->mount]}";
+ die "Failed to retrieve subvolume info for @{[$fs->mount]}\n";
}
- my @subvols = join("", @info) =~ m/Name:[ \t\n]*([^ \t\n]*)/;
- if ($#subvols > 0) {
+ my @ids = join("", @id_info) =~ m/Object ID:[ \t\n]*([^ \t\n]*)/;
+ if ($#ids > 0) {
die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n"
- } elsif ($#subvols == 0) {
- $path = "/$subvols[0]$path";
+ } elsif ($#ids == 0) {
+ my ($status, @path_info) = runCommand("btrfs subvol list @{[$fs->mount]}");
+ if ($status != 0) {
+ die "Failed to find @{[$fs->mount]} subvolume id from btrfs\n";
+ }
+ my @paths = join("", @path_info) =~ m/ID $ids[0] [^\n]* path ([^\n]*)/;
+ if ($#paths > 0) {
+ die "Btrfs returned multiple paths for a single subvolume id, mountpoint @{[$fs->mount]}\n";
+ } elsif ($#paths != 0) {
+ die "Btrfs did not return a path for the subvolume at @{[$fs->mount]}\n";
+ }
+ $path = "/$paths[0]$path";
}
}
}
@@ -154,11 +207,9 @@ sub GrubFs {
return Grub->new(path => $path, search => $search);
}
my $grubBoot = GrubFs("/boot");
-my $grubStore = GrubFs("/nix");
-
-# We don't need to copy if we can read the kernels directly
-if ($grubStore->search ne "") {
- $copyKernels = 0;
+my $grubStore;
+if ($copyKernels == 0) {
+ $grubStore = GrubFs("/nix/store");
}
# Generate the header.
@@ -176,9 +227,12 @@ if ($grubVersion == 1) {
}
else {
+ if ($copyKernels == 0) {
+ $conf .= "
+ " . $grubStore->search;
+ }
$conf .= "
" . $grubBoot->search . "
- " . $grubStore->search . "
if [ -s \$prefix/grubenv ]; then
load_env
fi
@@ -235,7 +289,7 @@ mkpath("/boot/kernels", 0, 0755) if $copyKernels;
sub copyToKernelsDir {
my ($path) = @_;
- return $grubStore->path . substr($path, length("/nix")) unless $copyKernels;
+ return $grubStore->path . substr($path, length("/nix/store")) unless $copyKernels;
$path =~ /\/nix\/store\/(.*)/ or die;
my $name = $1; $name =~ s/\//-/g;
my $dst = "/boot/kernels/$name";
@@ -275,8 +329,10 @@ sub addEntry {
$conf .= " " . ($xen ? "module" : "initrd") . " $initrd\n\n";
} else {
$conf .= "menuentry \"$name\" {\n";
- $conf .= $grubBoot->search . "\n";
- $conf .= $grubStore->search . "\n";
+ $conf .= $grubBoot->search . "\n";
+ if ($copyKernels == 0) {
+ $conf .= $grubStore->search . "\n";
+ }
$conf .= " $extraPerEntryConfig\n" if $extraPerEntryConfig;
$conf .= " multiboot $xen $xenParams\n" if $xen;
$conf .= " " . ($xen ? "module" : "linux") . " $kernel $kernelParams\n";
@@ -293,8 +349,9 @@ addEntry("NixOS - Default", $defaultConfig);
$conf .= "$extraEntries\n" unless $extraEntriesBeforeNixOS;
+my $grubBootPath = $grubBoot->path;
# extraEntries could refer to @bootRoot@, which we have to substitute
-$conf =~ s/\@bootRoot\@/$grubBoot->path/g;
+$conf =~ s/\@bootRoot\@/$grubBootPath/g;
# Emit submenus for all system profiles.
sub addProfile {
@@ -353,16 +410,116 @@ foreach my $fn (glob "/boot/kernels/*") {
}
-# Install GRUB if the version changed from the last time we installed
-# it. FIXME: shouldn't we reinstall if ‘devices’ changed?
-my $prevVersion = readFile("/boot/grub/version") // "";
-if (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1" || get("fullVersion") ne $prevVersion) {
+#
+# Install GRUB if the parameters changed from the last time we installed it.
+#
+
+struct(GrubState => {
+ version => '$',
+ efi => '$',
+ devices => '$',
+ efiMountPoint => '$',
+});
+sub readGrubState {
+ my $defaultGrubState = GrubState->new(version => "", efi => "", devices => "", efiMountPoint => "" );
+ open FILE, ";
+ chomp($version);
+ my $efi = ;
+ chomp($efi);
+ my $devices = ;
+ chomp($devices);
+ my $efiMountPoint = ;
+ chomp($efiMountPoint);
+ close FILE;
+ my $grubState = GrubState->new(version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
+ return $grubState
+}
+
+sub getDeviceTargets {
+ my @devices = ();
foreach my $dev ($dom->findnodes('/expr/attrs/attr[@name = "devices"]/list/string/@value')) {
$dev = $dev->findvalue(".") or die;
+ push(@devices, $dev);
+ }
+ return @devices;
+}
+
+# check whether to install GRUB EFI or not
+sub getEfiTarget {
+ if ($grubVersion == 1) {
+ return "no"
+ } elsif (($grub ne "") && ($grubEfi ne "")) {
+ # EFI can only be installed when target is set;
+ # A target is also required then for non-EFI grub
+ if (($grubTarget eq "") || ($grubTargetEfi eq "")) { die }
+ else { return "both" }
+ } elsif (($grub ne "") && ($grubEfi eq "")) {
+ # TODO: It would be safer to disallow non-EFI grub installation if no taget is given.
+ # If no target is given, then grub auto-detects the target which can lead to errors.
+ # E.g. it seems as if grub would auto-detect a EFI target based on the availability
+ # of a EFI partition.
+ # However, it seems as auto-detection is currently relied on for non-x86_64 and non-i386
+ # architectures in NixOS. That would have to be fixed in the nixos modules first.
+ return "no"
+ } elsif (($grub eq "") && ($grubEfi ne "")) {
+ # EFI can only be installed when target is set;
+ if ($grubTargetEfi eq "") { die }
+ else {return "only" }
+ } else {
+ # at least one grub target has to be given
+ die
+ }
+}
+
+my @deviceTargets = getDeviceTargets();
+my $efiTarget = getEfiTarget();
+my $prevGrubState = readGrubState();
+my @prevDeviceTargets = split/:/, $prevGrubState->devices;
+
+my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference() );
+my $versionDiffer = (get("fullVersion") eq \$prevGrubState->version);
+my $efiDiffer = ($efiTarget eq \$prevGrubState->efi);
+my $efiMountPointDiffer = ($efiSysMountPoint eq \$prevGrubState->efiMountPoint);
+my $requireNewInstall = $devicesDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1");
+
+
+# install non-EFI GRUB
+if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
+ foreach my $dev (@deviceTargets) {
next if $dev eq "nodev";
print STDERR "installing the GRUB $grubVersion boot loader on $dev...\n";
- system("$grub/sbin/grub-install", "--recheck", Cwd::abs_path($dev)) == 0
- or die "$0: installation of GRUB on $dev failed\n";
+ if ($grubTarget eq "") {
+ system("$grub/sbin/grub-install", "--recheck", Cwd::abs_path($dev)) == 0
+ or die "$0: installation of GRUB on $dev failed\n";
+ } else {
+ system("$grub/sbin/grub-install", "--recheck", "--target=$grubTarget", Cwd::abs_path($dev)) == 0
+ or die "$0: installation of GRUB on $dev failed\n";
+ }
}
- writeFile("/boot/grub/version", get("fullVersion"));
+}
+
+
+# install EFI GRUB
+if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
+ print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
+ if ($canTouchEfiVariables eq "true") {
+ system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--efi-directory=$efiSysMountPoint") == 0
+ or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
+ } else {
+ system("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--efi-directory=$efiSysMountPoint", "--no-nvram") == 0
+ or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
+ }
+}
+
+
+# update GRUB state file
+if ($requireNewInstall != 0) {
+ open FILE, ">/boot/grub/state" or die "cannot create /boot/grub/state: $!\n";
+ print FILE get("fullVersion"), "\n" or die;
+ print FILE $efiTarget, "\n" or die;
+ print FILE join( ":", @deviceTargets ), "\n" or die;
+ print FILE $efiSysMountPoint, "\n" or die;
+ close FILE or die;
}
diff --git a/nixos/modules/system/boot/loader/grub/ipxe.nix b/nixos/modules/system/boot/loader/grub/ipxe.nix
new file mode 100644
index 00000000000..9b5097a4cfd
--- /dev/null
+++ b/nixos/modules/system/boot/loader/grub/ipxe.nix
@@ -0,0 +1,64 @@
+# This module adds a scripted iPXE entry to the GRUB boot menu.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ scripts = builtins.attrNames config.boot.loader.grub.ipxe;
+
+ grubEntry = name:
+ ''
+ menuentry "iPXE - ${name}" {
+ linux16 @bootRoot@/ipxe.lkrn
+ initrd16 @bootRoot@/${name}.ipxe
+ }
+
+ '';
+
+ scriptFile = name:
+ let
+ value = builtins.getAttr name config.boot.loader.grub.ipxe;
+ in
+ if builtins.typeOf value == "path" then value
+ else builtins.toFile "${name}.ipxe" value;
+in
+{
+ options =
+ { boot.loader.grub.ipxe = mkOption {
+ type = types.attrsOf (types.either types.path types.str);
+ description =
+ ''
+ Set of iPXE scripts available for
+ booting from the GRUB boot menu.
+ '';
+ default = { };
+ example = literalExample ''
+ { demo = '''
+ #!ipxe
+ dhcp
+ chain http://boot.ipxe.org/demo/boot.php
+ ''';
+ };
+ '';
+ };
+ };
+
+ config = mkIf (builtins.length scripts != 0) {
+
+ boot.loader.grub.extraEntries =
+ if config.boot.loader.grub.version == 2 then
+ toString (map grubEntry scripts)
+ else
+ throw "iPXE is not supported with GRUB 1.";
+
+ boot.loader.grub.extraFiles =
+ { "ipxe.lkrn" = "${pkgs.ipxe}/ipxe.lkrn"; }
+ //
+ builtins.listToAttrs ( map
+ (name: { name = name+".ipxe"; value = scriptFile name; })
+ scripts
+ );
+ };
+
+}
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py b/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py
index db73544181b..ef431a7732e 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py
+++ b/nixos/modules/system/boot/loader/gummiboot/gummiboot-builder.py
@@ -63,7 +63,8 @@ def get_generations(profile):
"@nix@/bin/nix-env",
"--list-generations",
"-p",
- "/nix/var/nix/profiles/%s" % (profile)
+ "/nix/var/nix/profiles/%s" % (profile),
+ "--option", "build-users-group", ""
])
gen_lines = gen_list.split('\n')
gen_lines.pop()
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
index e7a481e90a7..6c201eb8212 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
+++ b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
@@ -16,7 +16,7 @@ let
nix = config.nix.package;
- inherit (cfg) timeout;
+ timeout = if cfg.timeout != null then cfg.timeout else "";
inherit (efi) efiSysMountPoint canTouchEfiVariables;
};
@@ -31,7 +31,7 @@ in {
};
timeout = mkOption {
- default = null;
+ default = if config.boot.loader.timeout == null then 10000 else config.boot.loader.timeout;
example = 4;
diff --git a/nixos/modules/system/boot/loader/init-script/init-script.nix b/nixos/modules/system/boot/loader/init-script/init-script.nix
index 3b33d42b4ae..374d9524ff1 100644
--- a/nixos/modules/system/boot/loader/init-script/init-script.nix
+++ b/nixos/modules/system/boot/loader/init-script/init-script.nix
@@ -23,6 +23,7 @@ in
enable = mkOption {
default = false;
+ type = types.bool;
description = ''
Some systems require a /sbin/init script which is started.
Or having it makes starting NixOS easier.
diff --git a/nixos/modules/system/boot/loader/loader.nix b/nixos/modules/system/boot/loader/loader.nix
new file mode 100644
index 00000000000..28cceafea7c
--- /dev/null
+++ b/nixos/modules/system/boot/loader/loader.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+ options = {
+ boot.loader.timeout = mkOption {
+ default = 5;
+ type = types.nullOr types.int;
+ description = ''
+ Timeout (in seconds) until loader boots the default menu item. Use null if the loader menu should be displayed indefinitely.
+ '';
+ };
+ };
+}
\ No newline at end of file
diff --git a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
index d3f32418a64..1ea3ddd8867 100644
--- a/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
+++ b/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
@@ -21,6 +21,7 @@ in
boot.loader.raspberryPi.enable = mkOption {
default = false;
+ type = types.bool;
description = ''
Whether to create files with the system generations in
/boot .
diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix
index 68392e3cfe2..20eee8e06e0 100644
--- a/nixos/modules/system/boot/luksroot.nix
+++ b/nixos/modules/system/boot/luksroot.nix
@@ -203,7 +203,7 @@ in
description = ''
Unless enabled, encryption keys can be easily recovered by an attacker with physical
access to any machine with PCMCIA, ExpressCard, ThunderBolt or FireWire port.
- More information: http://en.wikipedia.org/wiki/DMA_attack
+ More information is available at .
This option blacklists FireWire drivers, but doesn't remove them. You can manually
load the drivers if you need to use a FireWire device, but don't forget to unload them!
@@ -342,40 +342,39 @@ in
description = "Path where the ramfs used to update the LUKS key will be mounted in stage-1";
};
- storage = mkOption {
- type = types.optionSet;
- description = "Options related to the storing the salt";
+ /* TODO: Add to the documentation of the current module:
- options = {
- device = mkOption {
- default = "/dev/sda1";
- type = types.path;
- description = ''
- An unencrypted device that will temporarily be mounted in stage-1.
- Must contain the current salt to create the challenge for this LUKS device.
- '';
- };
+ Options related to the storing the salt.
+ */
+ storage = {
+ device = mkOption {
+ default = "/dev/sda1";
+ type = types.path;
+ description = ''
+ An unencrypted device that will temporarily be mounted in stage-1.
+ Must contain the current salt to create the challenge for this LUKS device.
+ '';
+ };
- fsType = mkOption {
- default = "vfat";
- type = types.string;
- description = "The filesystem of the unencrypted device";
- };
+ fsType = mkOption {
+ default = "vfat";
+ type = types.string;
+ description = "The filesystem of the unencrypted device";
+ };
- mountPoint = mkOption {
- default = "/crypt-storage";
- type = types.string;
- description = "Path where the unencrypted device will be mounted in stage-1";
- };
+ mountPoint = mkOption {
+ default = "/crypt-storage";
+ type = types.string;
+ description = "Path where the unencrypted device will be mounted in stage-1";
+ };
- path = mkOption {
- default = "/crypt-storage/default";
- type = types.string;
- description = ''
- Absolute path of the salt on the unencrypted device with
- that device's root directory as "/".
- '';
- };
+ path = mkOption {
+ default = "/crypt-storage/default";
+ type = types.string;
+ description = ''
+ Absolute path of the salt on the unencrypted device with
+ that device's root directory as "/".
+ '';
};
};
};
@@ -406,29 +405,19 @@ in
# copy the cryptsetup binary and it's dependencies
boot.initrd.extraUtilsCommands = ''
- cp -pdv ${pkgs.cryptsetup}/sbin/cryptsetup $out/bin
-
- cp -pdv ${pkgs.libgcrypt}/lib/libgcrypt*.so.* $out/lib
- cp -pdv ${pkgs.libgpgerror}/lib/libgpg-error*.so.* $out/lib
- cp -pdv ${pkgs.cryptsetup}/lib/libcryptsetup*.so.* $out/lib
- cp -pdv ${pkgs.popt}/lib/libpopt*.so.* $out/lib
+ copy_bin_and_libs ${pkgs.cryptsetup}/bin/cryptsetup
${optionalString luks.yubikeySupport ''
- cp -pdv ${pkgs.ykpers}/bin/ykchalresp $out/bin
- cp -pdv ${pkgs.ykpers}/bin/ykinfo $out/bin
- cp -pdv ${pkgs.openssl}/bin/openssl $out/bin
+ copy_bin_and_libs ${pkgs.ykpers}/bin/ykchalresp
+ copy_bin_and_libs ${pkgs.ykpers}/bin/ykinfo
+ copy_bin_and_libs ${pkgs.openssl}/bin/openssl
- cc -O3 -I${pkgs.openssl}/include -L${pkgs.openssl}/lib ${./pbkdf2-sha512.c} -o $out/bin/pbkdf2-sha512 -lcrypto
- strip -s $out/bin/pbkdf2-sha512
+ cc -O3 -I${pkgs.openssl}/include -L${pkgs.openssl}/lib ${./pbkdf2-sha512.c} -o pbkdf2-sha512 -lcrypto
+ strip -s pbkdf2-sha512
+ copy_bin_and_libs pbkdf2-sha512
- cp -pdv ${pkgs.libusb1}/lib/libusb*.so.* $out/lib
- cp -pdv ${pkgs.ykpers}/lib/libykpers*.so.* $out/lib
- cp -pdv ${pkgs.libyubikey}/lib/libyubikey*.so.* $out/lib
- cp -pdv ${pkgs.openssl}/lib/libssl*.so.* $out/lib
- cp -pdv ${pkgs.openssl}/lib/libcrypto*.so.* $out/lib
-
- mkdir -p $out/etc/ssl
- cp -pdv ${pkgs.openssl}/etc/ssl/openssl.cnf $out/etc/ssl
+ mkdir -p $out/etc/ssl
+ cp -pdv ${pkgs.openssl}/etc/ssl/openssl.cnf $out/etc/ssl
cat > $out/bin/openssl-wrap < $out/bin/$name
+ echo 'exec '$i' "$@"' >> $out/bin/$name
+ chmod +x $out/bin/$name
+ done
+ ln -s bin $out/sbin
+ '';
text =
''
#! ${pkgs.stdenv.shell}
@@ -26,7 +34,6 @@ with lib;
MODULE_DIR=/run/booted-system/kernel-modules/lib/modules/
fi
- exec ${pkgs.kmod}/sbin/modprobe "$@"
'';
};
description = ''
@@ -77,6 +84,11 @@ with lib;
'')}
${config.boot.extraModprobeConfig}
'';
+ environment.etc."modprobe.d/usb-load-ehci-first.conf".text =
+ ''
+ softdep uhci_hcd pre: ehci_hcd
+ softdep ohci_hcd pre: ehci_hcd
+ '';
environment.systemPackages = [ config.system.sbin.modprobe pkgs.kmod ];
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index 73fc6ce543c..5af644279e5 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -7,6 +7,8 @@ export LD_LIBRARY_PATH=@extraUtils@/lib
export PATH=@extraUtils@/bin
ln -s @extraUtils@/bin /bin
+# Stop LVM complaining about fd3
+export LVM_SUPPRESS_FD_WARNINGS=true
fail() {
if [ -n "$panicOnFail" ]; then exit 1; fi
@@ -34,7 +36,7 @@ EOF
read reply
if [ -n "$allowShell" -a "$reply" = f ]; then
- exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console"
+ exec setsid @shell@ -c "exec @shell@ < /dev/$console >/dev/$console 2>/dev/$console"
elif [ -n "$allowShell" -a "$reply" = i ]; then
echo "Starting interactive shell..."
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
@@ -56,9 +58,10 @@ echo
# Mount special file systems.
-mkdir -p /etc
+mkdir -p /etc/udev
touch /etc/fstab # to shut up mount
touch /etc/mtab # to shut up mke2fs
+touch /etc/udev/hwdb.bin # to shut up udev
touch /etc/initrd-release
mkdir -p /proc
mount -t proc proc /proc
@@ -122,6 +125,9 @@ for o in $(cat /proc/cmdline); do
esac
done
+# Set hostid before modules are loaded.
+# This is needed by the spl/zfs modules.
+@setHostId@
# Load the required kernel modules.
mkdir -p /lib
@@ -168,9 +174,28 @@ if test -e /sys/power/tuxonice/resume; then
fi
fi
-if test -n "@resumeDevice@" -a -e /sys/power/resume -a -e /sys/power/disk; then
- echo "@resumeDevice@" > /sys/power/resume 2> /dev/null || echo "failed to resume..."
- echo shutdown > /sys/power/disk
+if test -e /sys/power/resume -a -e /sys/power/disk; then
+ if test -n "@resumeDevice@"; then
+ resumeDev="@resumeDevice@"
+ resumeInfo="$(udevadm info -q property "$resumeDev" )"
+ else
+ for sd in @resumeDevices@; do
+ # Try to detect resume device. According to Ubuntu bug:
+ # https://bugs.launchpad.net/ubuntu/+source/pm-utils/+bug/923326/comments/1
+ # When there are multiple swap devices, we can't know where will hibernate
+ # image reside. We can check all of them for swsuspend blkid.
+ resumeInfo="$(udevadm info -q property "$sd" )"
+ if [ "$(echo "$resumeInfo" | sed -n 's/^ID_FS_TYPE=//p')" = "swsuspend" ]; then
+ resumeDev="$sd"
+ break
+ fi
+ done
+ fi
+ if test -e "$resumeDev"; then
+ resumeMajor="$(echo "$resumeInfo" | sed -n 's/^MAJOR=//p')"
+ resumeMinor="$(echo "$resumeInfo" | sed -n 's/^MINOR=//p')"
+ echo "$resumeMajor:$resumeMinor" > /sys/power/resume 2> /dev/null || echo "failed to resume..."
+ fi
fi
@@ -197,6 +222,9 @@ checkFS() {
# Don't check resilient COWs as they validate the fs structures at mount time
if [ "$fsType" = btrfs -o "$fsType" = zfs ]; then return 0; fi
+ # Skip fsck for inherently readonly filesystems.
+ if [ "$fsType" = squashfs ]; then return 0; fi
+
# If we couldn't figure out the FS type, then skip fsck.
if [ "$fsType" = auto ]; then
echo 'cannot check filesystem with type "auto"!'
@@ -328,7 +356,8 @@ while read -u 3 mountPoint; do
# that we don't properly recognise.
if test -z "$pseudoDevice" -a ! -e $device; then
echo -n "waiting for device $device to appear..."
- for try in $(seq 1 20); do
+ try=20
+ while [ $try -gt 0 ]; do
sleep 1
# also re-try lvm activation now that new block devices might have appeared
lvm vgchange -ay
@@ -336,8 +365,12 @@ while read -u 3 mountPoint; do
udevadm trigger --action=add
if test -e $device; then break; fi
echo -n "."
+ try=$((try - 1))
done
echo
+ if [ $try -eq 0 ]; then
+ echo "Timed out waiting for device $device, trying to mount anyway."
+ fi
fi
# Wait once more for the udev queue to empty, just in case it's
@@ -353,6 +386,18 @@ exec 3>&-
@postMountCommands@
+# Emit a udev rule for /dev/root to prevent systemd from complaining.
+if [ -e /mnt-root/iso ]; then
+ eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=/mnt-root/iso || true)
+else
+ eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=$targetRoot || true)
+fi
+if [ "$ROOT_MAJOR" -a "$ROOT_MINOR" -a "$ROOT_MAJOR" != 0 ]; then
+ mkdir -p /run/udev/rules.d
+ echo 'ACTION=="add|change", SUBSYSTEM=="block", ENV{MAJOR}=="'$ROOT_MAJOR'", ENV{MINOR}=="'$ROOT_MINOR'", SYMLINK+="root"' > /run/udev/rules.d/61-dev-root-link.rules
+fi
+
+
# Stop udevd.
udevadm control --exit || true
@@ -371,7 +416,7 @@ echo /sbin/modprobe > /proc/sys/kernel/modprobe
# Start stage 2. `switch_root' deletes all files in the ramfs on the
# current root. Note that $stage2Init might be an absolute symlink,
# in which case "-e" won't work because we're not in the chroot yet.
-if ! test -e "$targetRoot/$stage2Init" -o -L "$targetRoot/$stage2Init"; then
+if ! test -e "$targetRoot/$stage2Init" -o ! -L "$targetRoot/$stage2Init"; then
echo "stage 2 init script ($targetRoot/$stage2Init) not found"
fail
fi
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index 426da778f43..8b58eccdcec 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -34,49 +34,65 @@ let
doublePatchelf = pkgs.stdenv.isArm;
}
''
+ set +o pipefail
+
mkdir -p $out/bin $out/lib
ln -s $out/bin $out/sbin
- # Copy what we need from Glibc.
- cp -pv ${pkgs.glibc}/lib/ld*.so.? $out/lib
- cp -pv ${pkgs.glibc}/lib/libc.so.* $out/lib
- cp -pv ${pkgs.glibc}/lib/libm.so.* $out/lib
- cp -pv ${pkgs.glibc}/lib/libpthread.so.* $out/lib
- cp -pv ${pkgs.glibc}/lib/librt.so.* $out/lib
- cp -pv ${pkgs.glibc}/lib/libdl.so.* $out/lib
- cp -pv ${pkgs.gcc.gcc}/lib*/libgcc_s.so.* $out/lib
+ copy_bin_and_libs () {
+ [ -f "$out/bin/$(basename $1)" ] && rm "$out/bin/$(basename $1)"
+ cp -pdv $1 $out/bin
+ }
# Copy BusyBox.
- cp -pvd ${pkgs.busybox}/bin/* ${pkgs.busybox}/sbin/* $out/bin/
+ for BIN in ${pkgs.busybox}/{s,}bin/*; do
+ copy_bin_and_libs $BIN
+ done
# Copy some utillinux stuff.
- cp -vf ${pkgs.utillinux}/sbin/blkid $out/bin
- cp -pdv ${pkgs.utillinux}/lib/libblkid*.so.* $out/lib
- cp -pdv ${pkgs.utillinux}/lib/libuuid*.so.* $out/lib
+ copy_bin_and_libs ${pkgs.utillinux}/sbin/blkid
# Copy dmsetup and lvm.
- cp -v ${pkgs.lvm2}/sbin/dmsetup $out/bin/dmsetup
- cp -v ${pkgs.lvm2}/sbin/lvm $out/bin/lvm
- cp -v ${pkgs.lvm2}/lib/libdevmapper.so.*.* $out/lib
- cp -v ${pkgs.systemd}/lib/libsystemd.so.* $out/lib
+ copy_bin_and_libs ${pkgs.lvm2}/sbin/dmsetup
+ copy_bin_and_libs ${pkgs.lvm2}/sbin/lvm
# Add RAID mdadm tool.
- cp -v ${pkgs.mdadm}/sbin/mdadm $out/bin/mdadm
+ copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm
# Copy udev.
- cp -v ${udev}/lib/systemd/systemd-udevd ${udev}/bin/udevadm $out/bin
- cp -v ${udev}/lib/udev/*_id $out/bin
- cp -pdv ${udev}/lib/libudev.so.* $out/lib
- cp -v ${pkgs.kmod}/lib/libkmod.so.* $out/lib
- cp -v ${pkgs.acl}/lib/libacl.so.* $out/lib
- cp -v ${pkgs.attr}/lib/libattr.so.* $out/lib
+ copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd
+ copy_bin_and_libs ${udev}/bin/udevadm
+ for BIN in ${udev}/lib/udev/*_id; do
+ copy_bin_and_libs $BIN
+ done
# Copy modprobe.
- cp -v ${pkgs.kmod}/bin/kmod $out/bin/
+ copy_bin_and_libs ${pkgs.kmod}/bin/kmod
ln -sf kmod $out/bin/modprobe
${config.boot.initrd.extraUtilsCommands}
+ # Copy ld manually since it isn't detected correctly
+ cp -pv ${pkgs.glibc}/lib/ld*.so.? $out/lib
+
+ # Copy all of the needed libraries for the binaries
+ for BIN in $(find $out/{bin,sbin} -type f); do
+ echo "Copying libs for bin $BIN"
+ LDD="$(ldd $BIN)" || continue
+ LIBS="$(echo "$LDD" | awk '{print $3}' | sed '/^$/d')"
+ for LIB in $LIBS; do
+ [ ! -f "$out/lib/$(basename $LIB)" ] && cp -pdv $LIB $out/lib
+ while [ "$(readlink $LIB)" != "" ]; do
+ LINK="$(readlink $LIB)"
+ if [ "${LINK:0:1}" != "/" ]; then
+ LINK="$(dirname $LIB)/$LINK"
+ fi
+ LIB="$LINK"
+ [ ! -f "$out/lib/$(basename $LIB)" ] && cp -pdv $LIB $out/lib
+ done
+ done
+ done
+
# Strip binaries further than normal.
chmod -R u+w $out
stripDirs "lib bin" "-s"
@@ -98,10 +114,11 @@ let
echo "testing patched programs..."
$out/bin/ash -c 'echo hello world' | grep "hello world"
export LD_LIBRARY_PATH=$out/lib
- $out/bin/mount --help 2>&1 | grep "BusyBox"
+ $out/bin/mount --help 2>&1 | grep -q "BusyBox"
+ $out/bin/blkid --help 2>&1 | grep -q 'libblkid'
$out/bin/udevadm --version
- $out/bin/dmsetup --version 2>&1 | tee -a log | grep "version:"
- LVM_SYSTEM_DIR=$out $out/bin/lvm version 2>&1 | tee -a log | grep "LVM"
+ $out/bin/dmsetup --version 2>&1 | tee -a log | grep -q "version:"
+ LVM_SYSTEM_DIR=$out $out/bin/lvm version 2>&1 | tee -a log | grep -q "LVM"
$out/bin/mdadm --version
${config.boot.initrd.extraUtilsCommandsTest}
@@ -127,7 +144,7 @@ let
cp -v ${udev}/lib/udev/rules.d/60-persistent-storage.rules $out/
cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/
cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/
- cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
+ ${config.boot.initrd.extraUdevRulesCommands}
for i in $out/*.rules; do
substituteInPlace $i \
@@ -137,7 +154,8 @@ let
--replace ${pkgs.utillinux}/sbin/blkid ${extraUtils}/bin/blkid \
--replace /sbin/blkid ${extraUtils}/bin/blkid \
--replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \
- --replace /sbin/mdadm ${extraUtils}/bin/mdadm
+ --replace /sbin/mdadm ${extraUtils}/bin/mdadm \
+ --replace /bin/sh ${extraUtils}/bin/sh
done
# Work around a bug in QEMU, which doesn't implement the "READ
@@ -181,16 +199,28 @@ let
inherit (config.boot.initrd) checkJournalingFS
preLVMCommands postDeviceCommands postMountCommands kernelModules;
+ resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
+ (filter (sd: sd ? label || hasPrefix "/dev/" sd.device) config.swapDevices);
+
fsInfo =
let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ];
in pkgs.writeText "initrd-fsinfo" (concatStringsSep "\n" (concatMap f fileSystems));
+
+ setHostId = optionalString (config.networking.hostId != null) ''
+ hi="${config.networking.hostId}"
+ ${if pkgs.stdenv.isBigEndian then ''
+ echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > /etc/hostid
+ '' else ''
+ echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > /etc/hostid
+ ''}
+ '';
};
# The closure of the init script of boot stage 1 is what we put in
# the initial RAM disk.
initialRamdisk = pkgs.makeInitrd {
- inherit (config.boot.initrd) compressor;
+ inherit (config.boot.initrd) compressor prepend;
contents =
[ { object = bootStage1;
@@ -220,13 +250,23 @@ in
options = {
boot.resumeDevice = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "8:2";
+ type = types.str;
+ default = "";
+ example = "/dev/sda3";
description = ''
- Device for manual resume attempt during boot, specified using
- the device's major and minor number as
- major :minor .
+ Device for manual resume attempt during boot. This should be used primarily
+ if you want to resume from file. If left empty, the swap partitions are used.
+ Specify here the device where the file resides.
+ You should also use boot.kernelParams to specify
+ resume_offset .
+ '';
+ };
+
+ boot.initrd.prepend = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ Other initrd files to prepend to the final initrd we are building.
'';
};
@@ -296,9 +336,20 @@ in
'';
};
+ boot.initrd.extraUdevRulesCommands = mkOption {
+ internal = true;
+ default = "";
+ type = types.lines;
+ description = ''
+ Shell commands to be executed in the builder of the
+ udev-rules derivation. This can be used to add
+ additional udev rules in the initial ramdisk.
+ '';
+ };
+
boot.initrd.compressor = mkOption {
internal = true;
- default = "gzip -9";
+ default = "gzip -9n";
type = types.str;
description = "The compressor to use on the initrd image.";
example = "xz";
@@ -328,10 +379,17 @@ in
config = mkIf (!config.boot.isContainer) {
- assertions = singleton
+ assertions = [
{ assertion = any (fs: fs.mountPoint == "/") (attrValues config.fileSystems);
message = "The ‘fileSystems’ option does not specify your root file system.";
- };
+ }
+ { assertion = let inherit (config.boot) resumeDevice; in
+ resumeDevice == "" || builtins.substring 0 1 resumeDevice == "/";
+ message = "boot.resumeDevice has to be an absolute path."
+ + " Old \"x:y\" style is no longer supported.";
+ }
+ ];
+
system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk;
@@ -342,9 +400,6 @@ in
(isYes "BLK_DEV_INITRD")
];
- # Prevent systemd from waiting for the /dev/root symlink.
- systemd.units."dev-root.device".text = "";
-
boot.initrd.supportedFilesystems = map (fs: fs.fsType) fileSystems;
};
diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh
index 6fff776f858..173453a17f7 100644
--- a/nixos/modules/system/boot/stage-2-init.sh
+++ b/nixos/modules/system/boot/stage-2-init.sh
@@ -50,8 +50,10 @@ echo "booting system configuration $systemConfig" > /dev/kmsg
# Make /nix/store a read-only bind mount to enforce immutability of
# the Nix store. Note that we can't use "chown root:nixbld" here
# because users/groups might not exist yet.
-chown 0:30000 /nix/store
-chmod 1775 /nix/store
+# Silence chown/chmod to fail gracefully on a readonly filesystem
+# like squashfs.
+chown -f 0:30000 /nix/store
+chmod -f 1775 /nix/store
if [ -n "@readOnlyStore@" ]; then
if ! readonly-mountpoint /nix/store; then
mount --bind /nix/store /nix/store
@@ -91,6 +93,7 @@ mkdir -m 01777 -p /tmp
mkdir -m 0755 -p /var /var/log /var/lib /var/db
mkdir -m 0755 -p /nix/var
mkdir -m 0700 -p /root
+chmod 0700 /root
mkdir -m 0755 -p /bin # for the /bin/sh symlink
mkdir -m 0755 -p /home
mkdir -m 0755 -p /etc/nixos
@@ -141,8 +144,6 @@ fi
# Use /etc/resolv.conf supplied by systemd-nspawn, if applicable.
if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then
cat /etc/resolv.conf | resolvconf -m 1000 -a host
-else
- touch /etc/resolv.conf
fi
diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix
index a6183c47eb1..2f4786c7896 100644
--- a/nixos/modules/system/boot/systemd-unit-options.nix
+++ b/nixos/modules/system/boot/systemd-unit-options.nix
@@ -4,15 +4,184 @@ with lib;
let
- checkService = v:
- let assertValueOneOf = name: values: attr:
- let val = getAttr name attr;
- in optional ( hasAttr name attr && !elem val values) "Systemd service field `${name}' cannot have value `${val}'.";
- checkType = assertValueOneOf "Type" ["simple" "forking" "oneshot" "dbus" "notify" "idle"];
- checkRestart = assertValueOneOf "Restart" ["no" "on-success" "on-failure" "on-abort" "always"];
- errors = concatMap (c: c v) [checkType checkRestart];
- in if errors == [] then true
- else builtins.trace (concatStringsSep "\n" errors) false;
+ boolValues = [true false "yes" "no"];
+
+ assertValueOneOf = name: values: group: attr:
+ optional (attr ? ${name} && !elem attr.${name} values)
+ "Systemd ${group} field `${name}' cannot have value `${attr.${name}}'.";
+
+ assertHasField = name: group: attr:
+ optional (!(attr ? ${name}))
+ "Systemd ${group} field `${name}' must exist.";
+
+ assertOnlyFields = fields: group: attr:
+ let badFields = filter (name: ! elem name fields) (attrNames attr); in
+ optional (badFields != [ ])
+ "Systemd ${group} has extra fields [${concatStringsSep " " badFields}].";
+
+ assertRange = name: min: max: group: attr:
+ optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name}))
+ "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";
+
+ digits = map toString (range 0 9);
+
+ isByteFormat = s:
+ let
+ l = reverseList (stringToCharacters s);
+ suffix = head l;
+ nums = tail l;
+ in elem suffix (["K" "M" "G" "T"] ++ digits)
+ && all (num: elem num digits) nums;
+
+ assertByteFormat = name: group: attr:
+ optional (attr ? ${name} && ! isByteFormat attr.${name})
+ "Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT].";
+
+ hexChars = stringToCharacters "0123456789abcdefABCDEF";
+
+ isMacAddress = s: stringLength s == 17
+ && flip all (splitString ":" s) (bytes:
+ all (byte: elem byte hexChars) (stringToCharacters bytes)
+ );
+
+ assertMacAddress = name: group: attr:
+ optional (attr ? ${name} && ! isMacAddress attr.${name})
+ "Systemd ${group} field `${name}' must be a valid mac address.";
+
+ checkUnitConfig = group: checks: v:
+ let errors = concatMap (c: c group v) checks; in
+ if errors == [] then true
+ else builtins.trace (concatStringsSep "\n" errors) false;
+
+ checkService = checkUnitConfig "Service" [
+ (assertValueOneOf "Type" [
+ "simple" "forking" "oneshot" "dbus" "notify" "idle"
+ ])
+ (assertValueOneOf "Restart" [
+ "no" "on-success" "on-failure" "on-abnormal" "on-abort" "always"
+ ])
+ ];
+
+ checkLink = checkUnitConfig "Link" [
+ (assertOnlyFields [
+ "Description" "Alias" "MACAddressPolicy" "MACAddress" "NamePolicy" "Name"
+ "MTUBytes" "BitsPerSecond" "Duplex" "WakeOnLan"
+ ])
+ (assertValueOneOf "MACAddressPolicy" ["persistent" "random"])
+ (assertMacAddress "MACAddress")
+ (assertValueOneOf "NamePolicy" [
+ "kernel" "database" "onboard" "slot" "path" "mac"
+ ])
+ (assertByteFormat "MTUBytes")
+ (assertByteFormat "BitsPerSecond")
+ (assertValueOneOf "Duplex" ["half" "full"])
+ (assertValueOneOf "WakeOnLan" ["phy" "magic" "off"])
+ ];
+
+ checkNetdev = checkUnitConfig "Netdev" [
+ (assertOnlyFields [
+ "Description" "Name" "Kind" "MTUBytes" "MACAddress"
+ ])
+ (assertHasField "Name")
+ (assertHasField "Kind")
+ (assertValueOneOf "Kind" [
+ "bridge" "bond" "vlan" "macvlan" "vxlan" "ipip"
+ "gre" "sit" "vti" "veth" "tun" "tap" "dummy"
+ ])
+ (assertByteFormat "MTUBytes")
+ (assertMacAddress "MACAddress")
+ ];
+
+ checkVlan = checkUnitConfig "VLAN" [
+ (assertOnlyFields ["Id"])
+ (assertRange "Id" 0 4094)
+ ];
+
+ checkMacvlan = checkUnitConfig "MACVLAN" [
+ (assertOnlyFields ["Mode"])
+ (assertValueOneOf "Mode" ["private" "vepa" "bridge" "passthru"])
+ ];
+
+ checkVxlan = checkUnitConfig "VXLAN" [
+ (assertOnlyFields ["Id" "Group" "TOS" "TTL" "MacLearning"])
+ (assertRange "TTL" 0 255)
+ (assertValueOneOf "MacLearning" boolValues)
+ ];
+
+ checkTunnel = checkUnitConfig "Tunnel" [
+ (assertOnlyFields ["Local" "Remote" "TOS" "TTL" "DiscoverPathMTU"])
+ (assertRange "TTL" 0 255)
+ (assertValueOneOf "DiscoverPathMTU" boolValues)
+ ];
+
+ checkPeer = checkUnitConfig "Peer" [
+ (assertOnlyFields ["Name" "MACAddress"])
+ (assertMacAddress "MACAddress")
+ ];
+
+ tunTapChecks = [
+ (assertOnlyFields ["OneQueue" "MultiQueue" "PacketInfo" "User" "Group"])
+ (assertValueOneOf "OneQueue" boolValues)
+ (assertValueOneOf "MultiQueue" boolValues)
+ (assertValueOneOf "PacketInfo" boolValues)
+ ];
+
+ checkTun = checkUnitConfig "Tun" tunTapChecks;
+
+ checkTap = checkUnitConfig "Tap" tunTapChecks;
+
+ checkBond = checkUnitConfig "Bond" [
+ (assertOnlyFields [
+ "Mode" "TransmitHashPolicy" "LACPTransmitRate" "MIIMonitorSec"
+ "UpDelaySec" "DownDelaySec"
+ ])
+ (assertValueOneOf "Mode" [
+ "balance-rr" "active-backup" "balance-xor"
+ "broadcast" "802.3ad" "balance-tlb" "balance-alb"
+ ])
+ (assertValueOneOf "TransmitHashPolicy" [
+ "layer2" "layer3+4" "layer2+3" "encap2+3" "802.3ad" "encap3+4"
+ ])
+ (assertValueOneOf "LACPTransmitRate" ["slow" "fast"])
+ ];
+
+ checkNetwork = checkUnitConfig "Network" [
+ (assertOnlyFields [
+ "Description" "DHCP" "DHCPServer" "IPv4LL" "IPv4LLRoute"
+ "LLMNR" "Domains" "Bridge" "Bond"
+ ])
+ (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
+ (assertValueOneOf "DHCPServer" boolValues)
+ (assertValueOneOf "IPv4LL" boolValues)
+ (assertValueOneOf "IPv4LLRoute" boolValues)
+ (assertValueOneOf "LLMNR" boolValues)
+ ];
+
+ checkAddress = checkUnitConfig "Address" [
+ (assertOnlyFields ["Address" "Peer" "Broadcast" "Label"])
+ (assertHasField "Address")
+ ];
+
+ checkRoute = checkUnitConfig "Route" [
+ (assertOnlyFields ["Gateway" "Destination" "Metric"])
+ (assertHasField "Gateway")
+ ];
+
+ checkDhcp = checkUnitConfig "DHCP" [
+ (assertOnlyFields [
+ "UseDNS" "UseMTU" "SendHostname" "UseHostname" "UseDomains" "UseRoutes"
+ "CriticalConnections" "VendorClassIdentifier" "RequestBroadcast"
+ "RouteMetric"
+ ])
+ (assertValueOneOf "UseDNS" boolValues)
+ (assertValueOneOf "UseMTU" boolValues)
+ (assertValueOneOf "SendHostname" boolValues)
+ (assertValueOneOf "UseHostname" boolValues)
+ (assertValueOneOf "UseDomains" boolValues)
+ (assertValueOneOf "UseRoutes" boolValues)
+ (assertValueOneOf "CriticalConnections" boolValues)
+ (assertValueOneOf "RequestBroadcast" boolValues)
+ ];
unitOption = mkOptionType {
name = "systemd option";
@@ -140,6 +309,15 @@ in rec {
'';
};
+ requisite = mkOption {
+ default = [];
+ type = types.listOf types.str;
+ description = ''
+ Similar to requires. However if the units listed are not started,
+ they will not be started and the transaction will fail.
+ '';
+ };
+
unitConfig = mkOption {
default = {};
example = { RequiresMountsFor = "/data"; };
@@ -230,6 +408,15 @@ in rec {
'';
};
+ reload = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Shell commands executed when the service's main process
+ is reloaded.
+ '';
+ };
+
preStop = mkOption {
type = types.lines;
default = "";
@@ -432,4 +619,345 @@ in rec {
targetOptions = commonUnitOptions;
+ commonNetworkOptions = {
+
+ enable = mkOption {
+ default = true;
+ type = types.bool;
+ description = ''
+ If set to false, this unit will be a symlink to
+ /dev/null.
+ '';
+ };
+
+ matchConfig = mkOption {
+ default = {};
+ example = { Name = "eth0"; };
+ type = types.attrsOf unitOption;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Match] section of the unit. See
+ systemd.link 5
+ systemd.netdev 5
+ systemd.network 5
+ for details.
+ '';
+ };
+
+ };
+
+ linkOptions = commonNetworkOptions // {
+
+ linkConfig = mkOption {
+ default = {};
+ example = { MACAddress = "00:ff:ee:aa:cc:dd"; };
+ type = types.addCheck (types.attrsOf unitOption) checkLink;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Link] section of the unit. See
+ systemd.link
+ 5 for details.
+ '';
+ };
+
+ };
+
+ netdevOptions = commonNetworkOptions // {
+
+ netdevConfig = mkOption {
+ default = {};
+ example = { Name = "mybridge"; Kind = "bridge"; };
+ type = types.addCheck (types.attrsOf unitOption) checkNetdev;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Netdev] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ vlanConfig = mkOption {
+ default = {};
+ example = { Id = "4"; };
+ type = types.addCheck (types.attrsOf unitOption) checkVlan;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [VLAN] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ macvlanConfig = mkOption {
+ default = {};
+ example = { Mode = "private"; };
+ type = types.addCheck (types.attrsOf unitOption) checkMacvlan;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [MACVLAN] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ vxlanConfig = mkOption {
+ default = {};
+ example = { Id = "4"; };
+ type = types.addCheck (types.attrsOf unitOption) checkVxlan;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [VXLAN] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ tunnelConfig = mkOption {
+ default = {};
+ example = { Remote = "192.168.1.1"; };
+ type = types.addCheck (types.attrsOf unitOption) checkTunnel;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Tunnel] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ peerConfig = mkOption {
+ default = {};
+ example = { Name = "veth2"; };
+ type = types.addCheck (types.attrsOf unitOption) checkPeer;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Peer] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ tunConfig = mkOption {
+ default = {};
+ example = { User = "openvpn"; };
+ type = types.addCheck (types.attrsOf unitOption) checkTun;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Tun] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ tapConfig = mkOption {
+ default = {};
+ example = { User = "openvpn"; };
+ type = types.addCheck (types.attrsOf unitOption) checkTap;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Tap] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ bondConfig = mkOption {
+ default = {};
+ example = { Mode = "802.3ad"; };
+ type = types.addCheck (types.attrsOf unitOption) checkBond;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Bond] section of the unit. See
+ systemd.netdev
+ 5 for details.
+ '';
+ };
+
+ };
+
+ addressOptions = {
+
+ addressConfig = mkOption {
+ default = {};
+ example = { Address = "192.168.0.100/24"; };
+ type = types.addCheck (types.attrsOf unitOption) checkAddress;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Address] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
+ routeOptions = {
+
+ routeConfig = mkOption {
+ default = {};
+ example = { Gateway = "192.168.0.1"; };
+ type = types.addCheck (types.attrsOf unitOption) checkRoute;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Route] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
+ networkOptions = commonNetworkOptions // {
+
+ networkConfig = mkOption {
+ default = {};
+ example = { Description = "My Network"; };
+ type = types.addCheck (types.attrsOf unitOption) checkNetwork;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [Network] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ dhcpConfig = mkOption {
+ default = {};
+ example = { UseDNS = true; UseRoutes = true; };
+ type = types.addCheck (types.attrsOf unitOption) checkDhcp;
+ description = ''
+ Each attribute in this set specifies an option in the
+ [DHCP] section of the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ name = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ The name of the network interface to match against.
+ '';
+ };
+
+ DHCP = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = ''
+ Whether to enable DHCP on the interfaces matched.
+ '';
+ };
+
+ domains = mkOption {
+ type = types.nullOr (types.listOf types.str);
+ default = null;
+ description = ''
+ A list of domains to pass to the network config.
+ '';
+ };
+
+ address = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of addresses to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ gateway = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of gateways to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ dns = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of dns servers to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ ntp = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of ntp servers to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ vlan = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of vlan interfaces to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ macvlan = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of macvlan interfaces to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ vxlan = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of vxlan interfaces to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ tunnel = mkOption {
+ default = [ ];
+ type = types.listOf types.str;
+ description = ''
+ A list of tunnel interfaces to be added to the network section of the
+ unit. See systemd.network
+ 5 for details.
+ '';
+ };
+
+ addresses = mkOption {
+ default = [ ];
+ type = types.listOf types.optionSet;
+ options = [ addressOptions ];
+ description = ''
+ A list of address sections to be added to the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ routes = mkOption {
+ default = [ ];
+ type = types.listOf types.optionSet;
+ options = [ routeOptions ];
+ description = ''
+ A list of route sections to be added to the unit. See
+ systemd.network
+ 5 for details.
+ '';
+ };
+
+ };
+
}
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index e353e9246b0..29c449d4d0b 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -1,7 +1,7 @@
{ config, lib, pkgs, utils, ... }:
-with lib;
with utils;
+with lib;
with import ./systemd-unit-options.nix { inherit config lib; };
let
@@ -10,15 +10,19 @@ let
systemd = cfg.package;
+
makeUnit = name: unit:
+ let
+ pathSafeName = lib.replaceChars ["@" ":" "\\"] ["-" "-" "-"] name;
+ in
if unit.enable then
- pkgs.runCommand "unit" { preferLocalBuild = true; inherit (unit) text; }
+ pkgs.runCommand "unit-${pathSafeName}" { preferLocalBuild = true; inherit (unit) text; }
''
mkdir -p $out
echo -n "$text" > $out/${shellEscape name}
''
else
- pkgs.runCommand "unit" { preferLocalBuild = true; }
+ pkgs.runCommand "unit-${pathSafeName}-disabled" { preferLocalBuild = true; }
''
mkdir -p $out
ln -s /dev/null $out/${shellEscape name}
@@ -32,6 +36,7 @@ let
"graphical.target"
"multi-user.target"
"network.target"
+ "network-pre.target"
"network-online.target"
"nss-lookup.target"
"nss-user-lookup.target"
@@ -81,6 +86,7 @@ let
"systemd-journal-flush.service"
"systemd-journal-gatewayd.socket"
"systemd-journal-gatewayd.service"
+ "systemd-journald-dev-log.socket"
"syslog.socket"
# SysV init compatibility.
@@ -91,6 +97,12 @@ let
"systemd-modules-load.service"
"kmod-static-nodes.service"
+ # Networking
+ "systemd-networkd.service"
+ "systemd-networkd-wait-online.service"
+ "systemd-resolved.service"
+ "systemd-timesyncd.service"
+
# Filesystems.
"systemd-fsck@.service"
"systemd-fsck-root.service"
@@ -207,6 +219,8 @@ let
{ PartOf = toString config.partOf; }
// optionalAttrs (config.conflicts != [])
{ Conflicts = toString config.conflicts; }
+ // optionalAttrs (config.requisite != [])
+ { Requisite = toString config.requisite; }
// optionalAttrs (config.restartTriggers != [])
{ X-Restart-Triggers = toString config.restartTriggers; }
// optionalAttrs (config.description != "") {
@@ -245,6 +259,12 @@ let
${config.postStart}
'';
})
+ (mkIf (config.reload != "")
+ { serviceConfig.ExecReload = makeJobScript "${name}-reload" ''
+ #! ${pkgs.stdenv.shell} -e
+ ${config.reload}
+ '';
+ })
(mkIf (config.preStop != "")
{ serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" ''
#! ${pkgs.stdenv.shell} -e
@@ -281,6 +301,19 @@ let
};
};
+ networkConfig = { name, config, ... }: {
+ config = {
+ matchConfig = optionalAttrs (config.name != null) {
+ Name = config.name;
+ };
+ networkConfig = optionalAttrs (config.DHCP != null) {
+ DHCP = config.DHCP;
+ } // optionalAttrs (config.domains != null) {
+ Domains = concatStringsSep " " config.domains;
+ };
+ };
+ };
+
toOption = x:
if x == true then "true"
else if x == false then "false"
@@ -315,7 +348,8 @@ let
[Service]
${let env = cfg.globalEnvironment // def.environment;
in concatMapStrings (n:
- let s = "Environment=\"${n}=${getAttr n env}\"\n";
+ let s = optionalString (env."${n}" != null)
+ "Environment=\"${n}=${env.${n}}\"\n";
in if stringLength s >= 2048 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)}
${if def.reloadIfChanged then ''
X-ReloadIfChanged=true
@@ -373,6 +407,103 @@ let
'';
};
+ commonMatchText = def: ''
+ [Match]
+ ${attrsToSection def.matchConfig}
+ '';
+
+ linkToUnit = name: def:
+ { inherit (def) enable;
+ text = commonMatchText def +
+ ''
+ [Link]
+ ${attrsToSection def.linkConfig}
+ '';
+ };
+
+ netdevToUnit = name: def:
+ { inherit (def) enable;
+ text = commonMatchText def +
+ ''
+ [NetDev]
+ ${attrsToSection def.netdevConfig}
+
+ ${optionalString (def.vlanConfig != { }) ''
+ [VLAN]
+ ${attrsToSection def.vlanConfig}
+
+ ''}
+ ${optionalString (def.macvlanConfig != { }) ''
+ [MACVLAN]
+ ${attrsToSection def.macvlanConfig}
+
+ ''}
+ ${optionalString (def.vxlanConfig != { }) ''
+ [VXLAN]
+ ${attrsToSection def.vxlanConfig}
+
+ ''}
+ ${optionalString (def.tunnelConfig != { }) ''
+ [Tunnel]
+ ${attrsToSection def.tunnelConfig}
+
+ ''}
+ ${optionalString (def.peerConfig != { }) ''
+ [Peer]
+ ${attrsToSection def.peerConfig}
+
+ ''}
+ ${optionalString (def.tunConfig != { }) ''
+ [Tun]
+ ${attrsToSection def.tunConfig}
+
+ ''}
+ ${optionalString (def.tapConfig != { }) ''
+ [Tap]
+ ${attrsToSection def.tapConfig}
+
+ ''}
+ ${optionalString (def.bondConfig != { }) ''
+ [Bond]
+ ${attrsToSection def.bondConfig}
+
+ ''}
+ '';
+ };
+
+ networkToUnit = name: def:
+ { inherit (def) enable;
+ text = commonMatchText def +
+ ''
+ [Network]
+ ${attrsToSection def.networkConfig}
+ ${concatStringsSep "\n" (map (s: "Address=${s}") def.address)}
+ ${concatStringsSep "\n" (map (s: "Gateway=${s}") def.gateway)}
+ ${concatStringsSep "\n" (map (s: "DNS=${s}") def.dns)}
+ ${concatStringsSep "\n" (map (s: "NTP=${s}") def.ntp)}
+ ${concatStringsSep "\n" (map (s: "VLAN=${s}") def.vlan)}
+ ${concatStringsSep "\n" (map (s: "MACVLAN=${s}") def.macvlan)}
+ ${concatStringsSep "\n" (map (s: "VXLAN=${s}") def.vxlan)}
+ ${concatStringsSep "\n" (map (s: "Tunnel=${s}") def.tunnel)}
+
+ ${optionalString (def.dhcpConfig != { }) ''
+ [DHCP]
+ ${attrsToSection def.dhcpConfig}
+
+ ''}
+ ${flip concatMapStrings def.addresses (x: ''
+ [Address]
+ ${attrsToSection x.addressConfig}
+
+ '')}
+ ${flip concatMapStrings def.routes (x: ''
+ [Route]
+ ${attrsToSection x.routeConfig}
+
+ '')}
+ '';
+ };
+
generateUnits = type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units" { preferLocalBuild = true; } ''
mkdir -p $out
@@ -457,8 +588,9 @@ let
mkdir -p $out/getty.target.wants/
ln -s ../autovt@tty1.service $out/getty.target.wants/
- ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \
- ../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
+ ln -s ../local-fs.target ../remote-fs.target ../network.target \
+ ../nss-lookup.target ../nss-user-lookup.target ../swap.target \
+ $out/multi-user.target.wants/
''}
''; # */
@@ -551,6 +683,47 @@ in
'';
};
+ systemd.network.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to enable networkd or not.
+ '';
+ };
+
+ systemd.network.links = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ linkOptions ];
+ description = "Definition of systemd network links.";
+ };
+
+ systemd.network.netdevs = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ netdevOptions ];
+ description = "Definition of systemd network devices.";
+ };
+
+ systemd.network.networks = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ networkOptions networkConfig ];
+ description = "Definition of systemd networks.";
+ };
+
+ systemd.network.units = mkOption {
+ description = "Definition of networkd units.";
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = { name, config, ... }:
+ { options = concreteUnitOptions;
+ config = {
+ unit = mkDefault (makeUnit name config);
+ };
+ };
+ };
+
systemd.defaultUnit = mkOption {
default = "multi-user.target";
type = types.str;
@@ -634,6 +807,22 @@ in
'';
};
+ services.resolved.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Enables the systemd dns resolver daemon.
+ '';
+ };
+
+ services.timesyncd.enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Enables the systemd ntp client daemon.
+ '';
+ };
+
systemd.tmpfiles.rules = mkOption {
type = types.listOf types.str;
default = [];
@@ -669,6 +858,13 @@ in
description = "Definition of systemd per-user service units.";
};
+ systemd.user.timers = mkOption {
+ default = {};
+ type = types.attrsOf types.optionSet;
+ options = [ timerOptions unitConfig ];
+ description = "Definition of systemd per-user timer units.";
+ };
+
systemd.user.sockets = mkOption {
default = {};
type = types.attrsOf types.optionSet;
@@ -690,7 +886,7 @@ in
###### implementation
- config = {
+ config = mkMerge [ {
warnings = concatLists (mapAttrsToList (name: service:
optional (service.serviceConfig.Type or "" == "oneshot" && service.serviceConfig.Restart or "no" != "no")
@@ -703,6 +899,9 @@ in
environment.etc."systemd/system".source =
generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
+ environment.etc."systemd/network".source =
+ generateUnits "network" cfg.network.units [] [];
+
environment.etc."systemd/user".source =
generateUnits "user" cfg.user.units upstreamUserUnits [];
@@ -755,6 +954,18 @@ in
unitConfig.X-StopOnReconfiguration = true;
};
+ systemd.targets.network-online.after = [ "ip-up.target" ];
+
+ systemd.targets.network-pre = {
+ wantedBy = [ "network.target" ];
+ before = [ "network.target" ];
+ };
+
+ systemd.targets.remote-fs-pre = {
+ wantedBy = [ "remote-fs.target" ];
+ before = [ "remote-fs.target" ];
+ };
+
systemd.units =
mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
@@ -768,9 +979,15 @@ in
(v: let n = escapeSystemdPath v.where;
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
+ systemd.network.units =
+ mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.network.links
+ // mapAttrs' (n: v: nameValuePair "${n}.netdev" (netdevToUnit n v)) cfg.network.netdevs
+ // mapAttrs' (n: v: nameValuePair "${n}.network" (networkToUnit n v)) cfg.network.networks;
+
systemd.user.units =
- mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
- // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets;
+ mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
+ // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets
+ // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.user.timers;
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
@@ -789,6 +1006,15 @@ in
users.extraUsers.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
users.extraGroups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
+ users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
+ users.extraGroups.systemd-network.gid = config.ids.gids.systemd-network;
+
+ users.extraUsers.systemd-resolve.uid = config.ids.uids.systemd-resolve;
+ users.extraGroups.systemd-resolve.gid = config.ids.gids.systemd-resolve;
+
+ users.extraUsers.systemd-timesync.uid = config.ids.uids.systemd-timesync;
+ users.extraGroups.systemd-timesync.gid = config.ids.gids.systemd-timesync;
+
# Generate timer units for all services that have a ‘startAt’ value.
systemd.timers =
mapAttrs (name: service:
@@ -814,6 +1040,11 @@ in
''
# This file is created automatically and should not be modified.
# Please change the option ‘systemd.tmpfiles.rules’ instead.
+
+ z /var/log/journal 2755 root systemd-journal - -
+ z /var/log/journal/%m 2755 root systemd-journal - -
+ z /var/log/journal/%m/* 0640 root systemd-journal - -
+
${concatStringsSep "\n" cfg.tmpfiles.rules}
'';
@@ -822,5 +1053,57 @@ in
systemd.services.systemd-remount-fs.restartIfChanged = false;
systemd.services.systemd-journal-flush.restartIfChanged = false;
- };
+ }
+ (mkIf config.systemd.network.enable {
+ systemd.services.systemd-networkd = {
+ wantedBy = [ "multi-user.target" ];
+ before = [ "network-interfaces.target" ];
+ restartTriggers = [ config.environment.etc."systemd/network".source ];
+ };
+
+ systemd.services.systemd-networkd-wait-online = {
+ before = [ "network-online.target" "ip-up.target" ];
+ wantedBy = [ "network-online.target" "ip-up.target" ];
+ };
+
+ systemd.services."systemd-network-wait-online@" = {
+ description = "Wait for Network Interface %I to be Configured";
+ conflicts = [ "shutdown.target" ];
+ requisite = [ "systemd-networkd.service" ];
+ after = [ "systemd-networkd.service" ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "${config.systemd.package}/lib/systemd/systemd-networkd-wait-online -i %I";
+ };
+ };
+
+ services.resolved.enable = mkDefault true;
+ services.timesyncd.enable = mkDefault config.services.ntp.enable;
+ })
+ (mkIf config.services.resolved.enable {
+ systemd.services.systemd-resolved = {
+ wantedBy = [ "multi-user.target" ];
+ restartTriggers = [ config.environment.etc."systemd/resolved.conf".source ];
+ };
+
+ environment.etc."systemd/resolved.conf".text = ''
+ [Resolve]
+ DNS=${concatStringsSep " " config.networking.nameservers}
+ '';
+ })
+ (mkIf config.services.timesyncd.enable {
+ systemd.services.systemd-timesyncd = {
+ wantedBy = [ "sysinit.target" ];
+ restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ];
+ };
+
+ environment.etc."systemd/timesyncd.conf".text = ''
+ [Time]
+ NTP=${concatStringsSep " " config.services.ntp.servers}
+ '';
+
+ systemd.services.ntpd.enable = false;
+ })
+ ];
}
diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl
index d7e15eccefc..89a49b972ff 100644
--- a/nixos/modules/system/etc/setup-etc.pl
+++ b/nixos/modules/system/etc/setup-etc.pl
@@ -12,8 +12,8 @@ sub atomicSymlink {
my ($source, $target) = @_;
my $tmp = "$target.tmp";
unlink $tmp;
- symlink $source, $tmp or return 1;
- rename $tmp, $target or return 1;
+ symlink $source, $tmp or return 0;
+ rename $tmp, $target or return 0;
return 1;
}
diff --git a/nixos/modules/tasks/bcache.nix b/nixos/modules/tasks/bcache.nix
new file mode 100644
index 00000000000..f988ec02af7
--- /dev/null
+++ b/nixos/modules/tasks/bcache.nix
@@ -0,0 +1,11 @@
+{ config, pkgs, ... }:
+
+{
+
+ environment.systemPackages = [ pkgs.bcache-tools ];
+
+ boot.initrd.extraUdevRulesCommands = ''
+ cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/
+ '';
+
+}
diff --git a/nixos/modules/tasks/cpu-freq.nix b/nixos/modules/tasks/cpu-freq.nix
index a8c63c13428..70bbee8474e 100644
--- a/nixos/modules/tasks/cpu-freq.nix
+++ b/nixos/modules/tasks/cpu-freq.nix
@@ -30,9 +30,7 @@ in
config = mkIf (!config.boot.isContainer && config.powerManagement.cpuFreqGovernor != null) {
- boot.kernelModules = [ "acpi-cpufreq" "speedstep-lib" "pcc-cpufreq"
- "cpufreq_${cfg.cpuFreqGovernor}"
- ];
+ boot.kernelModules = [ "cpufreq_${cfg.cpuFreqGovernor}" ];
environment.systemPackages = [ cpupower ];
diff --git a/nixos/modules/tasks/filesystems.nix b/nixos/modules/tasks/filesystems.nix
index 64a20034f3c..c6f2f072352 100644
--- a/nixos/modules/tasks/filesystems.nix
+++ b/nixos/modules/tasks/filesystems.nix
@@ -142,7 +142,10 @@ in
++ config.system.fsPackages;
environment.etc.fstab.text =
- ''
+ let
+ fsToSkipCheck = [ "none" "btrfs" "zfs" "tmpfs" "nfs" ];
+ skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
+ in ''
# This is a generated file. Do not edit!
# Filesystems.
@@ -154,7 +157,7 @@ in
+ " " + fs.fsType
+ " " + fs.options
+ " 0"
- + " " + (if fs.fsType == "none" || fs.device == "none" || fs.fsType == "btrfs" || fs.fsType == "tmpfs" || fs.noCheck then "0" else
+ + " " + (if skipCheck fs then "0" else
if fs.mountPoint == "/" then "1" else "2")
+ "\n"
)}
diff --git a/nixos/modules/tasks/filesystems/btrfs.nix b/nixos/modules/tasks/filesystems/btrfs.nix
index d0a2ac645e0..049f7708d73 100644
--- a/nixos/modules/tasks/filesystems/btrfs.nix
+++ b/nixos/modules/tasks/filesystems/btrfs.nix
@@ -17,13 +17,9 @@ in
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
- mkdir -p $out/bin
- cp -v ${pkgs.btrfsProgs}/bin/btrfs $out/bin
+ copy_bin_and_libs ${pkgs.btrfsProgs}/bin/btrfs
ln -sv btrfs $out/bin/btrfsck
ln -sv btrfsck $out/bin/fsck.btrfs
- # !!! Increases uncompressed initrd by 240k
- cp -pv ${pkgs.zlib}/lib/libz.so* $out/lib
- cp -pv ${pkgs.lzo}/lib/liblzo2.so* $out/lib
'';
boot.initrd.extraUtilsCommandsTest = mkIf inInitrd
diff --git a/nixos/modules/tasks/filesystems/cifs.nix b/nixos/modules/tasks/filesystems/cifs.nix
index c60f175db84..3932b5c9acf 100644
--- a/nixos/modules/tasks/filesystems/cifs.nix
+++ b/nixos/modules/tasks/filesystems/cifs.nix
@@ -18,7 +18,7 @@ in
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
- cp -v ${pkgs.cifs_utils}/sbin/mount.cifs $out/bin
+ copy_bin_and_libs ${pkgs.cifs_utils}/sbin/mount.cifs
'';
};
diff --git a/nixos/modules/tasks/filesystems/ext.nix b/nixos/modules/tasks/filesystems/ext.nix
index 24592e9d588..cc9d0ef37d5 100644
--- a/nixos/modules/tasks/filesystems/ext.nix
+++ b/nixos/modules/tasks/filesystems/ext.nix
@@ -10,12 +10,11 @@
boot.initrd.extraUtilsCommands =
''
# Copy e2fsck and friends.
- cp -v ${pkgs.e2fsprogs}/sbin/e2fsck $out/bin
- cp -v ${pkgs.e2fsprogs}/sbin/tune2fs $out/bin
+ copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/e2fsck
+ copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/tune2fs
ln -sv e2fsck $out/bin/fsck.ext2
ln -sv e2fsck $out/bin/fsck.ext3
ln -sv e2fsck $out/bin/fsck.ext4
- cp -pdv ${pkgs.e2fsprogs}/lib/lib*.so.* $out/lib
'';
};
diff --git a/nixos/modules/tasks/filesystems/f2fs.nix b/nixos/modules/tasks/filesystems/f2fs.nix
index 1ed7b1b6a62..430ac630a88 100644
--- a/nixos/modules/tasks/filesystems/f2fs.nix
+++ b/nixos/modules/tasks/filesystems/f2fs.nix
@@ -13,9 +13,7 @@ in
boot.initrd.availableKernelModules = mkIf inInitrd [ "f2fs" ];
boot.initrd.extraUtilsCommands = mkIf inInitrd ''
- mkdir -p $out/bin $out/lib
- cp -v ${pkgs.f2fs-tools}/sbin/fsck.f2fs $out/bin
- cp -pdv ${pkgs.f2fs-tools}/lib/lib*.so.* $out/lib
+ copy_bin_and_libs ${pkgs.f2fs-tools}/sbin/fsck.f2fs
'';
};
}
diff --git a/nixos/modules/tasks/filesystems/jfs.nix b/nixos/modules/tasks/filesystems/jfs.nix
new file mode 100644
index 00000000000..fc3905c7dc2
--- /dev/null
+++ b/nixos/modules/tasks/filesystems/jfs.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ inInitrd = any (fs: fs == "jfs") config.boot.initrd.supportedFilesystems;
+in
+{
+ config = mkIf (any (fs: fs == "jfs") config.boot.supportedFilesystems) {
+
+ system.fsPackages = [ pkgs.jfsutils ];
+
+ boot.initrd.kernelModules = mkIf inInitrd [ "jfs" ];
+
+ boot.initrd.extraUtilsCommands = mkIf inInitrd ''
+ copy_bin_and_libs ${pkgs.jfsutils}/sbin/fsck.jfs
+ '';
+ };
+}
diff --git a/nixos/modules/tasks/filesystems/nfs.nix b/nixos/modules/tasks/filesystems/nfs.nix
index e8c3d8ab56d..79de6556f25 100644
--- a/nixos/modules/tasks/filesystems/nfs.nix
+++ b/nixos/modules/tasks/filesystems/nfs.nix
@@ -13,7 +13,7 @@ let
idmapdConfFile = pkgs.writeText "idmapd.conf" ''
[General]
Pipefs-Directory = ${rpcMountpoint}
- ${optionalString (config.networking.domain != "")
+ ${optionalString (config.networking.domain != null)
"Domain = ${config.networking.domain}"}
[Mapping]
@@ -24,9 +24,33 @@ let
Method = nsswitch
'';
+ cfg = config.services.nfs;
+
in
{
+ ###### interface
+
+ options = {
+
+ services.nfs = {
+ statdPort = mkOption {
+ default = null;
+ example = 4000;
+ description = ''
+ Use fixed port for rpc.statd, useful if NFS server is behind firewall.
+ '';
+ };
+ lockdPort = mkOption {
+ default = null;
+ example = 4001;
+ description = ''
+ Use fixed port for NFS lock manager kernel module (lockd/nlockmgr),
+ useful if NFS server is behind firewall.
+ '';
+ };
+ };
+ };
###### implementation
@@ -34,7 +58,11 @@ in
services.rpcbind.enable = true;
- system.fsPackages = [ pkgs.nfsUtils ];
+ system.fsPackages = [ pkgs.nfs-utils ];
+
+ boot.extraModprobeConfig = mkIf (cfg.lockdPort != null) ''
+ options lockd nlm_udpport=${toString cfg.lockdPort} nlm_tcpport=${toString cfg.lockdPort}
+ '';
boot.kernelModules = [ "sunrpc" ];
@@ -43,12 +71,12 @@ in
systemd.services.statd =
{ description = "NFSv3 Network Status Monitor";
- path = [ pkgs.nfsUtils pkgs.sysvtools pkgs.utillinux ];
+ path = [ pkgs.nfs-utils pkgs.sysvtools pkgs.utillinux ];
- wantedBy = [ "network-online.target" "multi-user.target" ];
- before = [ "network-online.target" ];
+ wantedBy = [ "remote-fs-pre.target" ];
+ before = [ "remote-fs-pre.target" ];
requires = [ "basic.target" "rpcbind.service" ];
- after = [ "basic.target" "rpcbind.service" "network.target" ];
+ after = [ "basic.target" "rpcbind.service" ];
unitConfig.DefaultDependencies = false; # don't stop during shutdown
@@ -60,7 +88,10 @@ in
'';
serviceConfig.Type = "forking";
- serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.statd rpc.statd --no-notify";
+ serviceConfig.ExecStart = ''
+ @${pkgs.nfs-utils}/sbin/rpc.statd rpc.statd --no-notify \
+ ${if cfg.statdPort != null then "-p ${toString statdPort}" else ""}
+ '';
serviceConfig.Restart = "always";
};
@@ -69,8 +100,8 @@ in
path = [ pkgs.sysvtools pkgs.utillinux ];
- wantedBy = [ "network-online.target" "multi-user.target" ];
- before = [ "network-online.target" ];
+ wantedBy = [ "remote-fs-pre.target" ];
+ before = [ "remote-fs-pre.target" ];
requires = [ "rpcbind.service" ];
after = [ "rpcbind.service" ];
@@ -86,7 +117,7 @@ in
'';
serviceConfig.Type = "forking";
- serviceConfig.ExecStart = "@${pkgs.nfsUtils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}";
+ serviceConfig.ExecStart = "@${pkgs.nfs-utils}/sbin/rpc.idmapd rpc.idmapd -c ${idmapdConfFile}";
serviceConfig.Restart = "always";
};
diff --git a/nixos/modules/tasks/filesystems/reiserfs.nix b/nixos/modules/tasks/filesystems/reiserfs.nix
index a3bfb3fed8e..ab4c43e2ab8 100644
--- a/nixos/modules/tasks/filesystems/reiserfs.nix
+++ b/nixos/modules/tasks/filesystems/reiserfs.nix
@@ -17,8 +17,8 @@ in
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
- cp -v ${pkgs.reiserfsprogs}/sbin/reiserfsck $out/bin
- ln -sv reiserfsck $out/bin/fsck.reiserfs
+ copy_bin_and_libs ${pkgs.reiserfsprogs}/sbin/reiserfsck
+ ln -s reiserfsck $out/bin/fsck.reiserfs
'';
};
diff --git a/nixos/modules/tasks/filesystems/unionfs-fuse.nix b/nixos/modules/tasks/filesystems/unionfs-fuse.nix
index fe195e0db0b..3e38bffa3ba 100644
--- a/nixos/modules/tasks/filesystems/unionfs-fuse.nix
+++ b/nixos/modules/tasks/filesystems/unionfs-fuse.nix
@@ -7,9 +7,8 @@
boot.initrd.kernelModules = [ "fuse" ];
boot.initrd.extraUtilsCommands = ''
- cp -v ${pkgs.fuse}/lib/libfuse* $out/lib
- cp -v ${pkgs.fuse}/sbin/mount.fuse $out/bin
- cp -v ${pkgs.unionfs-fuse}/bin/unionfs $out/bin
+ copy_bin_and_libs ${pkgs.fuse}/sbin/mount.fuse
+ copy_bin_and_libs ${pkgs.unionfs-fuse}/bin/unionfs
substitute ${pkgs.unionfs-fuse}/sbin/mount.unionfs-fuse $out/bin/mount.unionfs-fuse \
--replace '${pkgs.bash}/bin/bash' /bin/sh \
--replace '${pkgs.fuse}/sbin' /bin \
diff --git a/nixos/modules/tasks/filesystems/vfat.nix b/nixos/modules/tasks/filesystems/vfat.nix
index 4cfe6e208f7..958e27ae8a3 100644
--- a/nixos/modules/tasks/filesystems/vfat.nix
+++ b/nixos/modules/tasks/filesystems/vfat.nix
@@ -17,7 +17,7 @@ in
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
- cp -v ${pkgs.dosfstools}/sbin/dosfsck $out/bin
+ copy_bin_and_libs ${pkgs.dosfstools}/sbin/dosfsck
ln -sv dosfsck $out/bin/fsck.vfat
'';
diff --git a/nixos/modules/tasks/filesystems/xfs.nix b/nixos/modules/tasks/filesystems/xfs.nix
index 5225b62a88c..d7c3930f4a3 100644
--- a/nixos/modules/tasks/filesystems/xfs.nix
+++ b/nixos/modules/tasks/filesystems/xfs.nix
@@ -17,7 +17,7 @@ in
boot.initrd.extraUtilsCommands = mkIf inInitrd
''
- cp -v ${pkgs.xfsprogs}/sbin/fsck.xfs $out/bin
+ copy_bin_and_libs ${pkgs.xfsprogs}/sbin/fsck.xfs
'';
# Trick just to set 'sh' after the extraUtils nuke-refs.
diff --git a/nixos/modules/tasks/filesystems/zfs.nix b/nixos/modules/tasks/filesystems/zfs.nix
index 1c4bbc16b49..d4b10e9ed09 100644
--- a/nixos/modules/tasks/filesystems/zfs.nix
+++ b/nixos/modules/tasks/filesystems/zfs.nix
@@ -1,11 +1,10 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
#
# todo:
# - crontab for scrubs, etc
# - zfs tunables
-# - /etc/zfs/zpool.cache handling
-
+with utils;
with lib;
let
@@ -22,15 +21,30 @@ let
kernel = config.boot.kernelPackages;
- splPkg = if cfgZfs.useGit then kernel.spl_git else kernel.spl;
- zfsPkg = if cfgZfs.useGit then kernel.zfs_git else kernel.zfs;
+ splKernelPkg = if cfgZfs.useGit then kernel.spl_git else kernel.spl;
+ zfsKernelPkg = if cfgZfs.useGit then kernel.zfs_git else kernel.zfs;
+ zfsUserPkg = if cfgZfs.useGit then pkgs.zfs_git else pkgs.zfs;
autosnapPkg = pkgs.zfstools.override {
- zfs = zfsPkg;
+ zfs = zfsUserPkg;
};
zfsAutoSnap = "${autosnapPkg}/bin/zfs-auto-snapshot";
+ datasetToPool = x: elemAt (splitString "/" x) 0;
+
+ fsToPool = fs: datasetToPool fs.device;
+
+ zfsFilesystems = filter (x: x.fsType == "zfs") (attrValues config.fileSystems);
+
+ isRoot = fs: fs.neededForBoot || elem fs.mountPoint [ "/" "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ];
+
+ allPools = unique ((map fsToPool zfsFilesystems) ++ cfgZfs.extraPools);
+
+ rootPools = unique (map fsToPool (filter isRoot zfsFilesystems));
+
+ dataPools = unique (filter (pool: !(elem pool rootPools)) allPools);
+
in
{
@@ -38,28 +52,73 @@ in
###### interface
options = {
- boot.spl.hostid = mkOption {
- default = "";
- example = "0xdeadbeef";
- description = ''
- ZFS uses a system's hostid to determine if a storage pool (zpool) is
- native to this system, and should thus be imported automatically.
- Unfortunately, this hostid can change under linux from boot to boot (by
- changing network adapters, for instance). Specify a unique 32 bit hostid in
- hex here for zfs to prevent getting a random hostid between boots and having to
- manually import pools.
- '';
- };
+ boot.zfs = {
+ useGit = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Use the git version of the SPL and ZFS packages.
+ Note that these are unreleased versions, with less testing, and therefore
+ may be more unstable.
+ '';
+ };
- boot.zfs.useGit = mkOption {
- type = types.bool;
- default = false;
- example = true;
- description = ''
- Use the git version of the SPL and ZFS packages.
- Note that these are unreleased versions, with less testing, and therefore
- may be more unstable.
- '';
+ extraPools = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "tank" "data" ];
+ description = ''
+ Name or GUID of extra ZFS pools that you wish to import during boot.
+
+ Usually this is not necessary. Instead, you should set the mountpoint property
+ of ZFS filesystems to legacy and add the ZFS filesystems to
+ NixOS's fileSystems option, which makes NixOS automatically
+ import the associated pool.
+
+ However, in some cases (e.g. if you have many filesystems) it may be preferable
+ to exclusively use ZFS commands to manage filesystems. If so, since NixOS/systemd
+ will not be managing those filesystems, you will need to specify the ZFS pool here
+ so that NixOS automatically imports it on every boot.
+ '';
+ };
+
+ forceImportRoot = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = ''
+ Forcibly import the ZFS root pool(s) during early boot.
+
+ This is enabled by default for backwards compatibility purposes, but it is highly
+ recommended to disable this option, as it bypasses some of the safeguards ZFS uses
+ to protect your ZFS pools.
+
+ If you set this option to false and NixOS subsequently fails to
+ boot because it cannot import the root pool, you should boot with the
+ zfs_force=1 option as a kernel parameter (e.g. by manually
+ editing the kernel params in grub during boot). You should only need to do this
+ once.
+ '';
+ };
+
+ forceImportAll = mkOption {
+ type = types.bool;
+ default = true;
+ example = false;
+ description = ''
+ Forcibly import all ZFS pool(s).
+
+ This is enabled by default for backwards compatibility purposes, but it is highly
+ recommended to disable this option, as it bypasses some of the safeguards ZFS uses
+ to protect your ZFS pools.
+
+ If you set this option to false and NixOS subsequently fails to
+ import your non-root ZFS pool(s), you should manually import each pool with
+ "zpool import -f <pool-name>", and then reboot. You should only need to do
+ this once.
+ '';
+ };
};
services.zfs.autoSnapshot = {
@@ -124,67 +183,113 @@ in
config = mkMerge [
(mkIf enableZfs {
+ assertions = [
+ {
+ assertion = config.networking.hostId != null;
+ message = "ZFS requires config.networking.hostId to be set";
+ }
+ {
+ assertion = !cfgZfs.forceImportAll || cfgZfs.forceImportRoot;
+ message = "If you enable boot.zfs.forceImportAll, you must also enable boot.zfs.forceImportRoot";
+ }
+ ];
+
boot = {
kernelModules = [ "spl" "zfs" ] ;
- extraModulePackages = [ splPkg zfsPkg ];
- extraModprobeConfig = mkIf (cfgSpl.hostid != "") ''
- options spl spl_hostid=${cfgSpl.hostid}
- '';
+ extraModulePackages = [ splKernelPkg zfsKernelPkg ];
};
boot.initrd = mkIf inInitrd {
kernelModules = [ "spl" "zfs" ];
extraUtilsCommands =
''
- cp -v ${zfsPkg}/sbin/zfs $out/bin
- cp -v ${zfsPkg}/sbin/zdb $out/bin
- cp -v ${zfsPkg}/sbin/zpool $out/bin
- cp -pdv ${zfsPkg}/lib/lib*.so* $out/lib
- cp -pdv ${pkgs.zlib}/lib/lib*.so* $out/lib
+ copy_bin_and_libs ${zfsUserPkg}/sbin/zfs
+ copy_bin_and_libs ${zfsUserPkg}/sbin/zdb
+ copy_bin_and_libs ${zfsUserPkg}/sbin/zpool
'';
- postDeviceCommands =
+ extraUtilsCommandsTest = mkIf inInitrd
''
- zpool import -f -a
+ $out/bin/zfs --help >/dev/null 2>&1
+ $out/bin/zpool --help >/dev/null 2>&1
'';
+ postDeviceCommands = concatStringsSep "\n" ([''
+ ZFS_FORCE="${optionalString cfgZfs.forceImportRoot "-f"}"
+
+ for o in $(cat /proc/cmdline); do
+ case $o in
+ zfs_force|zfs_force=1)
+ ZFS_FORCE="-f"
+ ;;
+ esac
+ done
+ ''] ++ (map (pool: ''
+ echo "importing root ZFS pool \"${pool}\"..."
+ zpool import -N $ZFS_FORCE "${pool}"
+ '') rootPools));
};
boot.loader.grub = mkIf inInitrd {
zfsSupport = true;
};
- systemd.services."zpool-import" = {
- description = "Import zpools";
- after = [ "systemd-udev-settle.service" ];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- ExecStart = "${zfsPkg}/sbin/zpool import -f -a";
- };
- restartIfChanged = false;
+ environment.etc."zfs/zed.d".source = "${zfsUserPkg}/etc/zfs/zed.d/*";
+
+ system.fsPackages = [ zfsUserPkg ]; # XXX: needed? zfs doesn't have (need) a fsck
+ environment.systemPackages = [ zfsUserPkg ];
+ services.udev.packages = [ zfsUserPkg ]; # to hook zvol naming, etc.
+ systemd.packages = [ zfsUserPkg ];
+
+ systemd.services = let
+ getPoolFilesystems = pool:
+ filter (x: x.fsType == "zfs" && (fsToPool x) == pool) (attrValues config.fileSystems);
+
+ getPoolMounts = pool:
+ let
+ mountPoint = fs: escapeSystemdPath fs.mountPoint;
+ in
+ map (x: "${mountPoint x}.mount") (getPoolFilesystems pool);
+
+ createImportService = pool:
+ nameValuePair "zfs-import-${pool}" {
+ description = "Import ZFS pool \"${pool}\"";
+ requires = [ "systemd-udev-settle.service" ];
+ after = [ "systemd-udev-settle.service" "systemd-modules-load.service" ];
+ wantedBy = (getPoolMounts pool) ++ [ "local-fs.target" ];
+ before = (getPoolMounts pool) ++ [ "local-fs.target" ];
+ unitConfig = {
+ DefaultDependencies = "no";
+ };
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+ script = ''
+ zpool_cmd="${zfsUserPkg}/sbin/zpool"
+ ("$zpool_cmd" list "${pool}" >/dev/null) || "$zpool_cmd" import -N ${optionalString cfgZfs.forceImportAll "-f"} "${pool}"
+ '';
+ };
+ in listToAttrs (map createImportService dataPools) // {
+ "zfs-mount" = { after = [ "systemd-modules-load.service" ]; };
+ "zfs-share" = { after = [ "systemd-modules-load.service" ]; };
+ "zed" = { after = [ "systemd-modules-load.service" ]; };
};
- systemd.services."zfs-mount" = {
- description = "Mount ZFS Volumes";
- after = [ "zpool-import.service" ];
- wantedBy = [ "local-fs.target" ];
- serviceConfig = {
- Type = "oneshot";
- RemainAfterExit = true;
- ExecStart = "${zfsPkg}/sbin/zfs mount -a";
- ExecStop = "${zfsPkg}/sbin/zfs umount -a";
- };
- restartIfChanged = false;
- };
+ systemd.targets."zfs-import" =
+ let
+ services = map (pool: "zfs-import-${pool}.service") dataPools;
+ in
+ {
+ requires = services;
+ after = services;
+ };
- system.fsPackages = [ zfsPkg ]; # XXX: needed? zfs doesn't have (need) a fsck
- environment.systemPackages = [ zfsPkg ];
- services.udev.packages = [ zfsPkg ]; # to hook zvol naming, etc.
+ systemd.targets."zfs".wantedBy = [ "multi-user.target" ];
})
(mkIf enableAutoSnapshots {
systemd.services."zfs-snapshot-frequent" = {
description = "ZFS auto-snapshotting every 15 mins";
- after = [ "zpool-import.service" ];
+ after = [ "zfs-import.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zfsAutoSnap} frequent ${toString cfgSnapshots.frequent}";
@@ -195,7 +300,7 @@ in
systemd.services."zfs-snapshot-hourly" = {
description = "ZFS auto-snapshotting every hour";
- after = [ "zpool-import.service" ];
+ after = [ "zfs-import.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zfsAutoSnap} hourly ${toString cfgSnapshots.hourly}";
@@ -206,7 +311,7 @@ in
systemd.services."zfs-snapshot-daily" = {
description = "ZFS auto-snapshotting every day";
- after = [ "zpool-import.service" ];
+ after = [ "zfs-import.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zfsAutoSnap} daily ${toString cfgSnapshots.daily}";
@@ -217,7 +322,7 @@ in
systemd.services."zfs-snapshot-weekly" = {
description = "ZFS auto-snapshotting every week";
- after = [ "zpool-import.service" ];
+ after = [ "zfs-import.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zfsAutoSnap} weekly ${toString cfgSnapshots.weekly}";
@@ -228,7 +333,7 @@ in
systemd.services."zfs-snapshot-monthly" = {
description = "ZFS auto-snapshotting every month";
- after = [ "zpool-import.service" ];
+ after = [ "zfs-import.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${zfsAutoSnap} monthly ${toString cfgSnapshots.monthly}";
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index 03c42404e5d..8d26998021d 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -22,6 +22,7 @@ in
# FIXME: still needed?
boot.extraTTYs = mkOption {
default = [];
+ type = types.listOf types.string;
example = ["tty8" "tty9"];
description = ''
Tty (virtual console) devices, in addition to the consoles on
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
new file mode 100644
index 00000000000..fd545a723e7
--- /dev/null
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -0,0 +1,354 @@
+{ config, lib, pkgs, utils, ... }:
+
+with utils;
+with lib;
+
+let
+
+ cfg = config.networking;
+ interfaces = attrValues cfg.interfaces;
+ hasVirtuals = any (i: i.virtual) interfaces;
+
+ # We must escape interfaces due to the systemd interpretation
+ subsystemDevice = interface:
+ "sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
+
+ interfaceIps = i:
+ i.ip4 ++ optionals cfg.enableIPv6 i.ip6
+ ++ optional (i.ipAddress != null) {
+ address = i.ipAddress;
+ prefixLength = i.prefixLength;
+ } ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
+ address = i.ipv6Address;
+ prefixLength = i.ipv6PrefixLength;
+ };
+
+ destroyBond = i: ''
+ while true; do
+ UPDATED=1
+ SLAVES=$(ip link | grep 'master ${i}' | awk -F: '{print $2}')
+ for I in $SLAVES; do
+ UPDATED=0
+ ip link set "$I" nomaster
+ done
+ [ "$UPDATED" -eq "1" ] && break
+ done
+ ip link set "${i}" down 2>/dev/null || true
+ ip link del "${i}" 2>/dev/null || true
+ '';
+
+in
+
+{
+
+ config = mkIf (!cfg.useNetworkd) {
+
+ systemd.services =
+ let
+
+ networkLocalCommands = {
+ after = [ "network-setup.service" ];
+ bindsTo = [ "network-setup.service" ];
+ };
+
+ networkSetup =
+ { description = "Networking Setup";
+
+ after = [ "network-interfaces.target" "network-pre.target" ];
+ before = [ "network.target" ];
+ wantedBy = [ "network.target" ];
+
+ unitConfig.ConditionCapability = "CAP_NET_ADMIN";
+
+ path = [ pkgs.iproute ];
+
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+
+ script =
+ ''
+ # Set the static DNS configuration, if given.
+ ${pkgs.openresolv}/sbin/resolvconf -m 1 -a static <, create a job ‘network-addresses-.service"
+ # that performs static address configuration. It has a "wants"
+ # dependency on ‘.service’, which is supposed to create
+ # the interface and need not exist (i.e. for hardware
+ # interfaces). It has a binds-to dependency on the actual
+ # network device, so it only gets started after the interface
+ # has appeared, and it's stopped when the interface
+ # disappears.
+ configureAddrs = i:
+ let
+ ips = interfaceIps i;
+ in
+ nameValuePair "network-addresses-${i.name}"
+ { description = "Addresss configuration of ${i.name}";
+ wantedBy = [ "network-interfaces.target" ];
+ before = [ "network-interfaces.target" ];
+ bindsTo = [ (subsystemDevice i.name) ];
+ after = [ (subsystemDevice i.name) "network-pre.target" ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute ];
+ script =
+ ''
+ echo "bringing up interface..."
+ ip link set "${i.name}" up
+
+ restart_network_interfaces=false
+ '' + flip concatMapStrings (ips) (ip:
+ let
+ address = "${ip.address}/${toString ip.prefixLength}";
+ in
+ ''
+ echo "checking ip ${address}..."
+ if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
+ echo "added ip ${address}..."
+ restart_network_setup=true
+ elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
+ echo "failed to add ${address}"
+ exit 1
+ fi
+ '')
+ + optionalString (ips != [ ])
+ ''
+ if [ "$restart_network_setup" = "true" ]; then
+ # Ensure that the default gateway remains set.
+ # (Flushing this interface may have removed it.)
+ ${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service
+ fi
+ ${config.systemd.package}/bin/systemctl start ip-up.target
+ '';
+ preStop =
+ ''
+ echo "releasing configured ip's..."
+ '' + flip concatMapStrings (ips) (ip:
+ let
+ address = "${ip.address}/${toString ip.prefixLength}";
+ in
+ ''
+ echo -n "Deleting ${address}..."
+ ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
+ echo ""
+ '');
+ };
+
+ createTunDevice = i: nameValuePair "${i.name}-netdev"
+ { description = "Virtual Network Interface ${i.name}";
+ requires = [ "dev-net-tun.device" ];
+ after = [ "dev-net-tun.device" "network-pre.target" ];
+ wantedBy = [ "network.target" (subsystemDevice i.name) ];
+ before = [ "network-interfaces.target" (subsystemDevice i.name) ];
+ path = [ pkgs.iproute ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+ script = ''
+ ip tuntap add dev "${i.name}" \
+ ${optionalString (i.virtualType != null) "mode ${i.virtualType}"} \
+ user "${i.virtualOwner}"
+ '';
+ postStop = ''
+ ip link del ${i.name}
+ '';
+ };
+
+ createBridgeDevice = n: v: nameValuePair "${n}-netdev"
+ (let
+ deps = map subsystemDevice v.interfaces;
+ in
+ { description = "Bridge Interface ${n}";
+ wantedBy = [ "network.target" (subsystemDevice n) ];
+ bindsTo = deps ++ optional v.rstp "mstpd.service";
+ partOf = optional v.rstp "mstpd.service";
+ after = [ "network-pre.target" "mstpd.service" ] ++ deps
+ ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
+ before = [ "network-interfaces.target" (subsystemDevice n) ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute ];
+ script = ''
+ # Remove Dead Interfaces
+ echo "Removing old bridge ${n}..."
+ ip link show "${n}" >/dev/null 2>&1 && ip link del "${n}"
+
+ echo "Adding bridge ${n}..."
+ ip link add name "${n}" type bridge
+
+ # Enslave child interfaces
+ ${flip concatMapStrings v.interfaces (i: ''
+ ip link set "${i}" master "${n}"
+ ip link set "${i}" up
+ '')}
+
+ # Enable stp on the interface
+ ${optionalString v.rstp ''
+ echo 2 >/sys/class/net/${n}/bridge/stp_state
+ ''}
+
+ ip link set "${n}" up
+ '';
+ postStop = ''
+ ip link set "${n}" down || true
+ ip link del "${n}" || true
+ '';
+ });
+
+ createBondDevice = n: v: nameValuePair "${n}-netdev"
+ (let
+ deps = map subsystemDevice v.interfaces;
+ in
+ { description = "Bond Interface ${n}";
+ wantedBy = [ "network.target" (subsystemDevice n) ];
+ bindsTo = deps;
+ after = [ "network-pre.target" ] ++ deps
+ ++ concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) v.interfaces;
+ before = [ "network-interfaces.target" (subsystemDevice n) ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute pkgs.gawk ];
+ script = ''
+ echo "Destroying old bond ${n}..."
+ ${destroyBond n}
+
+ echo "Creating new bond ${n}..."
+ ip link add name "${n}" type bond \
+ ${optionalString (v.mode != null) "mode ${toString v.mode}"} \
+ ${optionalString (v.miimon != null) "miimon ${toString v.miimon}"} \
+ ${optionalString (v.xmit_hash_policy != null) "xmit_hash_policy ${toString v.xmit_hash_policy}"} \
+ ${optionalString (v.lacp_rate != null) "lacp_rate ${toString v.lacp_rate}"}
+
+ # !!! There must be a better way to wait for the interface
+ while [ ! -d "/sys/class/net/${n}" ]; do sleep 0.1; done;
+
+ # Bring up the bond and enslave the specified interfaces
+ ip link set "${n}" up
+ ${flip concatMapStrings v.interfaces (i: ''
+ ip link set "${i}" down
+ ip link set "${i}" master "${n}"
+ '')}
+ '';
+ postStop = destroyBond n;
+ });
+
+ createMacvlanDevice = n: v: nameValuePair "${n}-netdev"
+ (let
+ deps = [ (subsystemDevice v.interface) ];
+ in
+ { description = "Vlan Interface ${n}";
+ wantedBy = [ "network.target" (subsystemDevice n) ];
+ bindsTo = deps;
+ after = [ "network-pre.target" ] ++ deps;
+ before = [ "network-interfaces.target" (subsystemDevice n) ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute ];
+ script = ''
+ # Remove Dead Interfaces
+ ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+ ip link add link "${v.interface}" name "${n}" type macvlan \
+ ${optionalString (v.mode != null) "mode ${v.mode}"}
+ ip link set "${n}" up
+ '';
+ postStop = ''
+ ip link delete "${n}"
+ '';
+ });
+
+ createSitDevice = n: v: nameValuePair "${n}-netdev"
+ (let
+ deps = optional (v.dev != null) (subsystemDevice v.dev);
+ in
+ { description = "6-to-4 Tunnel Interface ${n}";
+ wantedBy = [ "network.target" (subsystemDevice n) ];
+ bindsTo = deps;
+ after = [ "network-pre.target" ] ++ deps;
+ before = [ "network-interfaces.target" (subsystemDevice n) ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute ];
+ script = ''
+ # Remove Dead Interfaces
+ ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+ ip link add name "${n}" type sit \
+ ${optionalString (v.remote != null) "remote \"${v.remote}\""} \
+ ${optionalString (v.local != null) "local \"${v.local}\""} \
+ ${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \
+ ${optionalString (v.dev != null) "dev \"${v.dev}\""}
+ ip link set "${n}" up
+ '';
+ postStop = ''
+ ip link delete "${n}"
+ '';
+ });
+
+ createVlanDevice = n: v: nameValuePair "${n}-netdev"
+ (let
+ deps = [ (subsystemDevice v.interface) ];
+ in
+ { description = "Vlan Interface ${n}";
+ wantedBy = [ "network.target" (subsystemDevice n) ];
+ bindsTo = deps;
+ after = [ "network-pre.target" ] ++ deps;
+ before = [ "network-interfaces.target" (subsystemDevice n) ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ path = [ pkgs.iproute ];
+ script = ''
+ # Remove Dead Interfaces
+ ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+ ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}"
+ ip link set "${n}" up
+ '';
+ postStop = ''
+ ip link delete "${n}"
+ '';
+ });
+
+ in listToAttrs (
+ map configureAddrs interfaces ++
+ map createTunDevice (filter (i: i.virtual) interfaces))
+ // mapAttrs' createBridgeDevice cfg.bridges
+ // mapAttrs' createBondDevice cfg.bonds
+ // mapAttrs' createMacvlanDevice cfg.macvlans
+ // mapAttrs' createSitDevice cfg.sits
+ // mapAttrs' createVlanDevice cfg.vlans
+ // {
+ "network-setup" = networkSetup;
+ "network-local-commands" = networkLocalCommands;
+ };
+
+ services.udev.extraRules =
+ ''
+ KERNEL=="tun", TAG+="systemd"
+ '';
+
+ };
+
+}
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix
new file mode 100644
index 00000000000..8223c5a4941
--- /dev/null
+++ b/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -0,0 +1,179 @@
+{ config, lib, pkgs, utils, ... }:
+
+with utils;
+with lib;
+
+let
+
+ cfg = config.networking;
+ interfaces = attrValues cfg.interfaces;
+
+ interfaceIps = i:
+ i.ip4 ++ optionals cfg.enableIPv6 i.ip6
+ ++ optional (i.ipAddress != null) {
+ address = i.ipAddress;
+ prefixLength = i.prefixLength;
+ } ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
+ address = i.ipv6Address;
+ prefixLength = i.ipv6PrefixLength;
+ };
+
+ dhcpStr = useDHCP: if useDHCP == true || useDHCP == null then "both" else "none";
+
+ slaves =
+ concatLists (map (bond: bond.interfaces) (attrValues cfg.bonds))
+ ++ concatLists (map (bridge: bridge.interfaces) (attrValues cfg.bridges))
+ ++ map (sit: sit.dev) (attrValues cfg.sits)
+ ++ map (vlan: vlan.interface) (attrValues cfg.vlans);
+
+in
+
+{
+
+ config = mkIf cfg.useNetworkd {
+
+ assertions = [ {
+ assertion = cfg.defaultGatewayWindowSize == null;
+ message = "networking.defaultGatewayWindowSize is not supported by networkd.";
+ } ] ++ flip mapAttrsToList cfg.bridges (n: { rstp, ... }: {
+ assertion = !rstp;
+ message = "networking.bridges.${n}.rstp is not supported by networkd.";
+ });
+
+ systemd.services.dhcpcd.enable = mkDefault false;
+
+ systemd.services.network-local-commands = {
+ after = [ "systemd-networkd.service" ];
+ bindsTo = [ "systemd-networkd.service" ];
+ };
+
+ systemd.network =
+ let
+ domains = cfg.search ++ (optional (cfg.domain != null) cfg.domain);
+ genericNetwork = override: {
+ DHCP = override (dhcpStr cfg.useDHCP);
+ } // optionalAttrs (cfg.defaultGateway != null) {
+ gateway = override [ cfg.defaultGateway ];
+ } // optionalAttrs (cfg.defaultGateway6 != null) {
+ gateway = override [ cfg.defaultGateway6 ];
+ } // optionalAttrs (domains != [ ]) {
+ domains = override domains;
+ };
+ in mkMerge [ {
+ enable = true;
+ networks."99-main" = genericNetwork mkDefault;
+ }
+ (mkMerge (flip map interfaces (i: {
+ netdevs = mkIf i.virtual (
+ let
+ devType = if i.virtualType != null then i.virtualType
+ else (if hasPrefix "tun" i.name then "tun" else "tap");
+ in {
+ "40-${i.name}" = {
+ netdevConfig = {
+ Name = i.name;
+ Kind = devType;
+ };
+ "${devType}Config" = optionalAttrs (i.virtualOwner != null) {
+ User = i.virtualOwner;
+ };
+ };
+ });
+ networks."40-${i.name}" = mkMerge [ (genericNetwork mkDefault) {
+ name = mkDefault i.name;
+ DHCP = mkForce (dhcpStr
+ (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ]));
+ address = flip map (interfaceIps i)
+ (ip: "${ip.address}/${toString ip.prefixLength}");
+ } ];
+ })))
+ (mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
+ netdevs."40-${name}" = {
+ netdevConfig = {
+ Name = name;
+ Kind = "bridge";
+ };
+ };
+ networks = listToAttrs (flip map bridge.interfaces (bi:
+ nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
+ DHCP = mkOverride 0 (dhcpStr false);
+ networkConfig.Bridge = name;
+ } ])));
+ })))
+ (mkMerge (flip mapAttrsToList cfg.bonds (name: bond: {
+ netdevs."40-${name}" = {
+ netdevConfig = {
+ Name = name;
+ Kind = "bond";
+ };
+ bondConfig =
+ (optionalAttrs (bond.lacp_rate != null) {
+ LACPTransmitRate = bond.lacp_rate;
+ }) // (optionalAttrs (bond.miimon != null) {
+ MIIMonitorSec = bond.miimon;
+ }) // (optionalAttrs (bond.mode != null) {
+ Mode = bond.mode;
+ }) // (optionalAttrs (bond.xmit_hash_policy != null) {
+ TransmitHashPolicy = bond.xmit_hash_policy;
+ });
+ };
+ networks = listToAttrs (flip map bond.interfaces (bi:
+ nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
+ DHCP = mkOverride 0 (dhcpStr false);
+ networkConfig.Bond = name;
+ } ])));
+ })))
+ (mkMerge (flip mapAttrsToList cfg.macvlans (name: macvlan: {
+ netdevs."40-${name}" = {
+ netdevConfig = {
+ Name = name;
+ Kind = "macvlan";
+ };
+ macvlanConfig = optionalAttrs (macvlan.mode != null) { Mode = macvlan.mode; };
+ };
+ networks."40-${macvlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
+ macvlan = [ name ];
+ } ]);
+ })))
+ (mkMerge (flip mapAttrsToList cfg.sits (name: sit: {
+ netdevs."40-${name}" = {
+ netdevConfig = {
+ Name = name;
+ Kind = "sit";
+ };
+ tunnelConfig =
+ (optionalAttrs (sit.remote != null) {
+ Remote = sit.remote;
+ }) // (optionalAttrs (sit.local != null) {
+ Local = sit.local;
+ }) // (optionalAttrs (sit.ttl != null) {
+ TTL = sit.ttl;
+ });
+ };
+ networks = mkIf (sit.dev != null) {
+ "40-${sit.dev}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
+ tunnel = [ name ];
+ } ]);
+ };
+ })))
+ (mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: {
+ netdevs."40-${name}" = {
+ netdevConfig = {
+ Name = name;
+ Kind = "vlan";
+ };
+ vlanConfig.Id = vlan.id;
+ };
+ networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
+ vlan = [ name ];
+ } ]);
+ })))
+ ];
+
+ # We need to prefill the slaved devices with networking options
+ # This forces the network interface creator to initialize slaves.
+ networking.interfaces = listToAttrs (map (i: nameValuePair i { }) slaves);
+
+ };
+
+}
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 7dabe70f00c..71a721abba2 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -1,6 +1,7 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, pkgs, utils, ... }:
with lib;
+with utils;
let
@@ -10,6 +11,64 @@ let
hasSits = cfg.sits != { };
hasBonds = cfg.bonds != { };
+ slaves = concatMap (i: i.interfaces) (attrValues cfg.bonds)
+ ++ concatMap (i: i.interfaces) (attrValues cfg.bridges);
+
+ slaveIfs = map (i: cfg.interfaces.${i}) (filter (i: cfg.interfaces ? ${i}) slaves);
+
+ rstpBridges = flip filterAttrs cfg.bridges (_: { rstp, ... }: rstp);
+
+ needsMstpd = rstpBridges != { };
+
+ bridgeStp = optional needsMstpd (pkgs.writeTextFile {
+ name = "bridge-stp";
+ executable = true;
+ destination = "/bin/bridge-stp";
+ text = ''
+ #!${pkgs.stdenv.shell} -e
+ export PATH="${pkgs.mstpd}/bin"
+
+ BRIDGES=(${concatStringsSep " " (attrNames rstpBridges)})
+ for BRIDGE in $BRIDGES; do
+ if [ "$BRIDGE" = "$1" ]; then
+ if [ "$2" = "start" ]; then
+ mstpctl addbridge "$BRIDGE"
+ exit 0
+ elif [ "$2" = "stop" ]; then
+ mstpctl delbridge "$BRIDGE"
+ exit 0
+ fi
+ exit 1
+ fi
+ done
+ exit 1
+ '';
+ });
+
+ # We must escape interfaces due to the systemd interpretation
+ subsystemDevice = interface:
+ "sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
+
+ addrOpts = v:
+ assert v == 4 || v == 6;
+ {
+ address = mkOption {
+ type = types.str;
+ description = ''
+ IPv${toString v} address of the interface. Leave empty to configure the
+ interface using DHCP.
+ '';
+ };
+
+ prefixLength = mkOption {
+ type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128));
+ description = ''
+ Subnet mask of the interface, specified as the number of
+ bits in the prefix (${if v == 4 then "24" else "64"} ).
+ '';
+ };
+ };
+
interfaceOpts = { name, ... }: {
options = {
@@ -20,10 +79,46 @@ let
description = "Name of the interface.";
};
+ useDHCP = mkOption {
+ type = types.nullOr types.bool;
+ default = null;
+ description = ''
+ Whether this interface should be configured with dhcp.
+ Null implies the old behavior which depends on whether ip addresses
+ are specified or not.
+ '';
+ };
+
+ ip4 = mkOption {
+ default = [ ];
+ example = [
+ { address = "10.0.0.1"; prefixLength = 16; }
+ { address = "192.168.1.1"; prefixLength = 24; }
+ ];
+ type = types.listOf types.optionSet;
+ options = addrOpts 4;
+ description = ''
+ List of IPv4 addresses that will be statically assigned to the interface.
+ '';
+ };
+
+ ip6 = mkOption {
+ default = [ ];
+ example = [
+ { address = "fdfd:b3f0:482::1"; prefixLength = 48; }
+ { address = "2001:1470:fffd:2098::e006"; prefixLength = 64; }
+ ];
+ type = types.listOf types.optionSet;
+ options = addrOpts 6;
+ description = ''
+ List of IPv6 addresses that will be statically assigned to the interface.
+ '';
+ };
+
ipAddress = mkOption {
default = null;
example = "10.0.0.1";
- type = types.nullOr (types.str);
+ type = types.nullOr types.str;
description = ''
IP address of the interface. Leave empty to configure the
interface using DHCP.
@@ -41,27 +136,23 @@ let
};
subnetMask = mkOption {
- default = "";
- example = "255.255.255.0";
- type = types.str;
+ default = null;
description = ''
- Subnet mask of the interface, specified as a bitmask.
- This is deprecated; use prefixLength
- instead.
+ Defunct, supply the prefix length instead.
'';
};
ipv6Address = mkOption {
default = null;
example = "2001:1470:fffd:2098::e006";
- type = types.nullOr types.string;
+ type = types.nullOr types.str;
description = ''
IPv6 address of the interface. Leave empty to configure the
interface using NDP.
'';
};
- ipv6prefixLength = mkOption {
+ ipv6PrefixLength = mkOption {
default = 64;
example = 64;
type = types.int;
@@ -96,8 +187,6 @@ let
Whether this interface is virtual and should be created by tunctl.
This is mainly useful for creating bridges between a host a virtual
network such as VPN or a virtual machine.
-
- Defaults to tap device, unless interface contains "tun" in its name.
'';
};
@@ -109,6 +198,15 @@ let
'';
};
+ virtualType = mkOption {
+ default = null;
+ type = types.nullOr (types.addCheck types.str (v: v == "tun" || v == "tap"));
+ description = ''
+ The explicit type of interface to create. Accepts tun or tap strings.
+ Also accepts null to implicitly detect the type of device.
+ '';
+ };
+
proxyARP = mkOption {
default = false;
type = types.bool;
@@ -135,6 +233,10 @@ let
};
+ hexChars = stringToCharacters "0123456789abcdef";
+
+ isHexString = s: all (c: elem c hexChars) (stringToCharacters (toLower s));
+
in
{
@@ -145,27 +247,57 @@ in
networking.hostName = mkOption {
default = "nixos";
+ type = types.str;
description = ''
The name of the machine. Leave it empty if you want to obtain
it from a DHCP server (if using DHCP).
'';
};
+ networking.hostId = mkOption {
+ default = null;
+ example = "4e98920d";
+ type = types.nullOr types.str;
+ description = ''
+ The 32-bit host ID of the machine, formatted as 8 hexadecimal characters.
+
+ You should try to make this ID unique among your machines. You can
+ generate a random 32-bit ID using the following commands:
+
+ cksum /etc/machine-id | while read c rest; do printf "%x" $c; done
+
+ (this derives it from the machine-id that systemd generates) or
+
+ head -c4 /dev/urandom | od -A none -t x4
+ '';
+ };
+
networking.enableIPv6 = mkOption {
default = true;
+ type = types.bool;
description = ''
Whether to enable support for IPv6.
'';
};
networking.defaultGateway = mkOption {
- default = "";
+ default = null;
example = "131.211.84.1";
+ type = types.nullOr types.str;
description = ''
The default gateway. It can be left empty if it is auto-detected through DHCP.
'';
};
+ networking.defaultGateway6 = mkOption {
+ default = null;
+ example = "2001:4d0:1e04:895::1";
+ type = types.nullOr types.str;
+ description = ''
+ The default ipv6 gateway. It can be left empty if it is auto-detected through DHCP.
+ '';
+ };
+
networking.defaultGatewayWindowSize = mkOption {
default = null;
example = 524288;
@@ -194,8 +326,9 @@ in
};
networking.domain = mkOption {
- default = "";
+ default = null;
example = "home";
+ type = types.nullOr types.str;
description = ''
The domain. It can be left empty if it is auto-detected through DHCP.
'';
@@ -224,10 +357,10 @@ in
networking.interfaces = mkOption {
default = {};
example =
- { eth0 = {
- ipAddress = "131.211.84.78";
- subnetMask = "255.255.255.128";
- };
+ { eth0.ip4 = [ {
+ address = "131.211.84.78";
+ prefixLength = 25;
+ } ];
};
description = ''
The configuration for each network interface. If
@@ -264,6 +397,13 @@ in
"The physical network interfaces connected by the bridge.";
};
+ rstp = mkOption {
+ example = true;
+ default = false;
+ type = types.bool;
+ description = "Whether the bridge interface should enable rstp.";
+ };
+
};
};
@@ -291,10 +431,20 @@ in
interfaces = mkOption {
example = [ "enp4s0f0" "enp4s0f1" "wlan0" ];
- type = types.listOf types.string;
+ type = types.listOf types.str;
description = "The interfaces to bond together";
};
+ lacp_rate = mkOption {
+ default = null;
+ example = "fast";
+ type = types.nullOr types.str;
+ description = ''
+ Option specifying the rate in which we'll ask our link partner
+ to transmit LACPDU packets in 802.3ad mode.
+ '';
+ };
+
miimon = mkOption {
default = null;
example = 100;
@@ -310,7 +460,7 @@ in
mode = mkOption {
default = null;
example = "active-backup";
- type = types.nullOr types.string;
+ type = types.nullOr types.str;
description = ''
The mode which the bond will be running. The default mode for
the bonding driver is balance-rr, optimizing for throughput.
@@ -319,6 +469,47 @@ in
'';
};
+ xmit_hash_policy = mkOption {
+ default = null;
+ example = "layer2+3";
+ type = types.nullOr types.str;
+ description = ''
+ Selects the transmit hash policy to use for slave selection in
+ balance-xor, 802.3ad, and tlb modes.
+ '';
+ };
+
+ };
+ };
+
+ networking.macvlans = mkOption {
+ type = types.attrsOf types.optionSet;
+ default = { };
+ example = {
+ wan = {
+ interface = "enp2s0";
+ mode = "vepa";
+ };
+ };
+ description = ''
+ This option allows you to define macvlan interfaces which should
+ be automatically created.
+ '';
+ options = {
+
+ interface = mkOption {
+ example = "enp4s0";
+ type = types.string;
+ description = "The interface the macvlan will transmit packets through.";
+ };
+
+ mode = mkOption {
+ default = null;
+ type = types.nullOr types.str;
+ example = "vepa";
+ description = "The mode of the macvlan device.";
+ };
+
};
};
@@ -431,6 +622,16 @@ in
'';
};
+ networking.useNetworkd = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether we should use networkd as the network configuration backend or
+ the legacy script based system. Note that this option is experimental,
+ enable at your own risk.
+ '';
+ };
+
};
@@ -438,6 +639,20 @@ in
config = {
+ assertions =
+ (flip map interfaces (i: {
+ assertion = i.subnetMask == null;
+ message = "The networking.interfaces.${i.name}.subnetMask option is defunct. Use prefixLength instead.";
+ })) ++ (flip map slaveIfs (i: {
+ assertion = i.ip4 == [ ] && i.ipAddress == null && i.ip6 == [ ] && i.ipv6Address == null;
+ message = "The networking.interfaces.${i.name} must not have any defined ips when it is a slave.";
+ })) ++ [
+ {
+ assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId);
+ message = "Invalid value given to the networking.hostId option.";
+ }
+ ];
+
boot.kernelModules = [ ]
++ optional cfg.enableIPv6 "ipv6"
++ optional hasVirtuals "tun"
@@ -449,6 +664,45 @@ in
# from being created.
optionalString hasBonds "options bonding max_bonds=0";
+ boot.kernel.sysctl = {
+ "net.net.ipv4.conf.all.promote_secondaries" = true;
+ "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6);
+ "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
+ "net.ipv4.conf.all_forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
+ "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
+ } // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces)
+ (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))
+ ));
+
+ security.setuidPrograms = [ "ping" "ping6" ];
+
+ # Set the host and domain names in the activation script. Don't
+ # clear it if it's not configured in the NixOS configuration,
+ # since it may have been set by dhcpcd in the meantime.
+ system.activationScripts.hostname =
+ optionalString (cfg.hostName != "") ''
+ hostname "${cfg.hostName}"
+ '';
+ system.activationScripts.domain =
+ optionalString (cfg.domain != null) ''
+ domainname "${cfg.domain}"
+ '';
+
+ environment.etc = mkIf (cfg.hostId != null)
+ [
+ {
+ target = "hostid";
+ source = pkgs.runCommand "gen-hostid" {} ''
+ hi="${cfg.hostId}"
+ ${if pkgs.stdenv.isBigEndian then ''
+ echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > $out
+ '' else ''
+ echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > $out
+ ''}
+ '';
+ }
+ ];
+
environment.systemPackages =
[ pkgs.host
pkgs.iproute
@@ -458,324 +712,56 @@ in
pkgs.iw
pkgs.rfkill
pkgs.openresolv
- ]
- ++ optional (cfg.bridges != {}) pkgs.bridge_utils
- ++ optional hasVirtuals pkgs.tunctl
- ++ optional cfg.enableIPv6 pkgs.ndisc6;
-
- security.setuidPrograms = [ "ping" "ping6" ];
+ ] ++ bridgeStp;
systemd.targets."network-interfaces" =
{ description = "All Network Interfaces";
wantedBy = [ "network.target" ];
+ before = [ "network.target" ];
+ after = [ "network-pre.target" ];
unitConfig.X-StopOnReconfiguration = true;
};
- systemd.services =
- let
+ systemd.services = {
+ network-local-commands = {
+ description = "Extra networking commands.";
+ before = [ "network.target" ];
+ wantedBy = [ "network.target" ];
+ after = [ "network-pre.target" ];
+ unitConfig.ConditionCapability = "CAP_NET_ADMIN";
+ path = [ pkgs.iproute ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ script = ''
+ # Run any user-specified commands.
+ ${cfg.localCommands}
+ '';
+ };
+ } // (listToAttrs (flip map interfaces (i:
+ nameValuePair "network-link-${i.name}"
+ { description = "Link configuration of ${i.name}";
+ wantedBy = [ "network-interfaces.target" ];
+ before = [ "network-interfaces.target" ];
+ bindsTo = [ (subsystemDevice i.name) ];
+ after = [ (subsystemDevice i.name) "network-pre.target" ];
+ path = [ pkgs.iproute ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+ script =
+ ''
+ echo "Configuring link..."
+ '' + optionalString (i.macAddress != null) ''
+ echo "setting MAC address to ${i.macAddress}..."
+ ip link set "${i.name}" address "${i.macAddress}"
+ '' + optionalString (i.mtu != null) ''
+ echo "setting MTU to ${toString i.mtu}..."
+ ip link set "${i.name}" mtu "${toString i.mtu}"
+ '';
+ })));
- networkSetup =
- { description = "Networking Setup";
-
- after = [ "network-interfaces.target" ];
- before = [ "network.target" ];
- wantedBy = [ "network.target" ];
-
- unitConfig.ConditionCapability = "CAP_NET_ADMIN";
-
- path = [ pkgs.iproute ];
-
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
-
- script =
- ''
- # Set the static DNS configuration, if given.
- ${pkgs.openresolv}/sbin/resolvconf -m 1 -a static < /proc/sys/net/ipv6/conf/all/disable_ipv6
- fi
- ''}
-
- # Set the default gateway.
- ${optionalString (cfg.defaultGateway != "") ''
- # FIXME: get rid of "|| true" (necessary to make it idempotent).
- ip route add default via "${cfg.defaultGateway}" ${
- optionalString (cfg.defaultGatewayWindowSize != null)
- "window ${cfg.defaultGatewayWindowSize}"} || true
- ''}
-
- # Turn on forwarding if any interface has enabled proxy_arp.
- ${optionalString (any (i: i.proxyARP) interfaces) ''
- echo 1 > /proc/sys/net/ipv4/ip_forward
- ''}
-
- # Run any user-specified commands.
- ${cfg.localCommands}
- '';
- };
-
- # For each interface , create a job ‘-cfg.service"
- # that performs static configuration. It has a "wants"
- # dependency on ‘.service’, which is supposed to create
- # the interface and need not exist (i.e. for hardware
- # interfaces). It has a binds-to dependency on the actual
- # network device, so it only gets started after the interface
- # has appeared, and it's stopped when the interface
- # disappears.
- configureInterface = i: nameValuePair "${i.name}-cfg"
- (let mask =
- if i.prefixLength != null then toString i.prefixLength else
- if i.subnetMask != "" then i.subnetMask else "32";
- staticIPv6 = cfg.enableIPv6 && i.ipv6Address != null;
- in
- { description = "Configuration of ${i.name}";
- wantedBy = [ "network-interfaces.target" ];
- bindsTo = [ "sys-subsystem-net-devices-${i.name}.device" ];
- after = [ "sys-subsystem-net-devices-${i.name}.device" ];
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
- path = [ pkgs.iproute pkgs.gawk ];
- script =
- ''
- echo "bringing up interface..."
- ip link set "${i.name}" up
- ''
- + optionalString (i.macAddress != null)
- ''
- echo "setting MAC address to ${i.macAddress}..."
- ip link set "${i.name}" address "${i.macAddress}"
- ''
- + optionalString (i.mtu != null)
- ''
- echo "setting MTU to ${toString i.mtu}..."
- ip link set "${i.name}" mtu "${toString i.mtu}"
- ''
- + optionalString (i.ipAddress != null)
- ''
- cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}')
- # Only do a flush/add if it's necessary. This is
- # useful when the Nix store is accessed via this
- # interface (e.g. in a QEMU VM test).
- if [ "$cur" != "${i.ipAddress}/${mask}" ]; then
- echo "configuring interface..."
- ip -4 addr flush dev "${i.name}"
- ip -4 addr add "${i.ipAddress}/${mask}" dev "${i.name}"
- restart_network_setup=true
- else
- echo "skipping configuring interface"
- fi
- ''
- + optionalString (staticIPv6)
- ''
- # Only do a flush/add if it's necessary. This is
- # useful when the Nix store is accessed via this
- # interface (e.g. in a QEMU VM test).
- if ! ip -6 -o a show dev "${i.name}" | grep "${i.ipv6Address}/${toString i.ipv6prefixLength}"; then
- echo "configuring interface..."
- ip -6 addr flush dev "${i.name}"
- ip -6 addr add "${i.ipv6Address}/${toString i.ipv6prefixLength}" dev "${i.name}"
- restart_network_setup=true
- else
- echo "skipping configuring interface"
- fi
- ''
- + optionalString (i.ipAddress != null || staticIPv6)
- ''
- if [ restart_network_setup = true ]; then
- # Ensure that the default gateway remains set.
- # (Flushing this interface may have removed it.)
- ${config.systemd.package}/bin/systemctl try-restart --no-block network-setup.service
- fi
- ${config.systemd.package}/bin/systemctl start ip-up.target
- ''
- + optionalString i.proxyARP
- ''
- echo 1 > /proc/sys/net/ipv4/conf/${i.name}/proxy_arp
- ''
- + optionalString (i.proxyARP && cfg.enableIPv6)
- ''
- echo 1 > /proc/sys/net/ipv6/conf/${i.name}/proxy_ndp
- '';
- });
-
- createTunDevice = i: nameValuePair "${i.name}"
- { description = "Virtual Network Interface ${i.name}";
- requires = [ "dev-net-tun.device" ];
- after = [ "dev-net-tun.device" ];
- wantedBy = [ "network.target" ];
- requiredBy = [ "sys-subsystem-net-devices-${i.name}.device" ];
- serviceConfig =
- { Type = "oneshot";
- RemainAfterExit = true;
- ExecStart = "${pkgs.tunctl}/bin/tunctl -t '${i.name}' -u '${i.virtualOwner}'";
- ExecStop = "${pkgs.tunctl}/bin/tunctl -d '${i.name}'";
- };
- };
-
- createBridgeDevice = n: v:
- let
- deps = map (i: "sys-subsystem-net-devices-${i}.device") v.interfaces;
- in
- { description = "Bridge Interface ${n}";
- wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
- bindsTo = deps;
- after = deps;
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
- path = [ pkgs.bridge_utils pkgs.iproute ];
- script =
- ''
- # Remove Dead Interfaces
- ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
-
- brctl addbr "${n}"
-
- # Set bridge's hello time to 0 to avoid startup delays.
- brctl setfd "${n}" 0
-
- ${flip concatMapStrings v.interfaces (i: ''
- brctl addif "${n}" "${i}"
- ip link set "${i}" up
- ip addr flush dev "${i}"
-
- echo "bringing up network device ${n}..."
- ip link set "${n}" up
- '')}
-
- # !!! Should delete (brctl delif) any interfaces that
- # no longer belong to the bridge.
- '';
- postStop =
- ''
- ip link set "${n}" down
- brctl delbr "${n}"
- '';
- };
-
- createBondDevice = n: v:
- let
- deps = map (i: "sys-subsystem-net-devices-${i}.device") v.interfaces;
- in
- { description = "Bond Interface ${n}";
- wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
- bindsTo = deps;
- after = deps;
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
- path = [ pkgs.ifenslave pkgs.iproute ];
- script = ''
- # Remove Dead Interfaces
- ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
-
- ip link add "${n}" type bond
-
- # !!! There must be a better way to wait for the interface
- while [ ! -d /sys/class/net/${n} ]; do sleep 0.1; done;
-
- # Set the miimon and mode options
- ${optionalString (v.miimon != null)
- "echo ${toString v.miimon} > /sys/class/net/${n}/bonding/miimon"}
- ${optionalString (v.mode != null)
- "echo \"${v.mode}\" > /sys/class/net/${n}/bonding/mode"}
-
- # Bring up the bridge and enslave the specified interfaces
- ip link set "${n}" up
- ${flip concatMapStrings v.interfaces (i: ''
- ifenslave "${n}" "${i}"
- '')}
- '';
- postStop = ''
- ip link set "${n}" down
- ifenslave -d "${n}"
- ip link delete "${n}"
- '';
- };
-
- createSitDevice = n: v:
- let
- deps = optional (v.dev != null) "sys-subsystem-net-devices-${v.dev}.device";
- in
- { description = "6-to-4 Tunnel Interface ${n}";
- wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
- bindsTo = deps;
- after = deps;
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
- path = [ pkgs.iproute ];
- script = ''
- # Remove Dead Interfaces
- ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
- ip link add "${n}" type sit \
- ${optionalString (v.remote != null) "remote \"${v.remote}\""} \
- ${optionalString (v.local != null) "local \"${v.local}\""} \
- ${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \
- ${optionalString (v.dev != null) "dev \"${v.dev}\""}
- ip link set "${n}" up
- '';
- postStop = ''
- ip link delete "${n}"
- '';
- };
-
- createVlanDevice = n: v:
- let
- deps = [ "sys-subsystem-net-devices-${v.interface}.device" ];
- in
- { description = "Vlan Interface ${n}";
- wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
- bindsTo = deps;
- after = deps;
- serviceConfig.Type = "oneshot";
- serviceConfig.RemainAfterExit = true;
- path = [ pkgs.iproute ];
- script = ''
- # Remove Dead Interfaces
- ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
- ip link add link "${v.interface}" "${n}" type vlan id "${toString v.id}"
- ip link set "${n}" up
- '';
- postStop = ''
- ip link delete "${n}"
- '';
- };
-
- in listToAttrs (
- map configureInterface interfaces ++
- map createTunDevice (filter (i: i.virtual) interfaces))
- // mapAttrs createBridgeDevice cfg.bridges
- // mapAttrs createBondDevice cfg.bonds
- // mapAttrs createSitDevice cfg.sits
- // mapAttrs createVlanDevice cfg.vlans
- // { "network-setup" = networkSetup; };
-
- # Set the host and domain names in the activation script. Don't
- # clear it if it's not configured in the NixOS configuration,
- # since it may have been set by dhcpcd in the meantime.
- system.activationScripts.hostname =
- optionalString (config.networking.hostName != "") ''
- hostname "${config.networking.hostName}"
- '';
- system.activationScripts.domain =
- optionalString (config.networking.domain != "") ''
- domainname "${config.networking.domain}"
- '';
-
- services.udev.extraRules =
- ''
- KERNEL=="tun", TAG+="systemd"
- '';
+ services.mstpd = mkIf needsMstpd { enable = true; };
};
diff --git a/nixos/modules/tasks/swraid.nix b/nixos/modules/tasks/swraid.nix
index 3b4aa9875f2..8e972891971 100644
--- a/nixos/modules/tasks/swraid.nix
+++ b/nixos/modules/tasks/swraid.nix
@@ -8,4 +8,8 @@
boot.initrd.availableKernelModules = [ "md_mod" "raid0" "raid1" "raid456" ];
+ boot.initrd.extraUdevRulesCommands = ''
+ cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
+ '';
+
}
diff --git a/nixos/modules/tasks/trackpoint.nix b/nixos/modules/tasks/trackpoint.nix
index 5d1bb631b54..778cdc5d30d 100644
--- a/nixos/modules/tasks/trackpoint.nix
+++ b/nixos/modules/tasks/trackpoint.nix
@@ -16,7 +16,7 @@ with lib;
Enable sensitivity and speed configuration for trackpoints.
'';
};
-
+
sensitivity = mkOption {
default = 128;
example = 255;
@@ -44,7 +44,7 @@ with lib;
Enable scrolling while holding the middle mouse button.
'';
};
-
+
};
};
@@ -70,7 +70,7 @@ with lib;
''
Section "InputClass"
Identifier "Trackpoint Wheel Emulation"
- MatchProduct "TPPS/2 IBM TrackPoint|DualPoint Stick|Synaptics Inc. Composite TouchPad / TrackPoint|ThinkPad USB Keyboard with TrackPoint|USB Trackpoint pointing device|Composite TouchPad / TrackPoint"
+ MatchProduct "Elantech PS/2 TrackPoint|TPPS/2 IBM TrackPoint|DualPoint Stick|Synaptics Inc. Composite TouchPad / TrackPoint|ThinkPad USB Keyboard with TrackPoint|USB Trackpoint pointing device|Composite TouchPad / TrackPoint"
MatchDevicePath "/dev/input/event*"
Option "EmulateWheel" "true"
Option "EmulateWheelButton" "2"
diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix
index 54a376c9560..f37bbd0246d 100644
--- a/nixos/modules/testing/test-instrumentation.nix
+++ b/nixos/modules/testing/test-instrumentation.nix
@@ -38,6 +38,11 @@ let kernel = config.boot.kernelPackages.kernel; in
systemd.services."serial-getty@ttyS0".enable = false;
systemd.services."serial-getty@hvc0".enable = false;
+ # Don't use a pager when executing backdoor actions. Because we
+ # use a tty, commands like systemctl or nix-store get confused
+ # into thinking they're running interactively.
+ environment.variables.PAGER = "";
+
boot.initrd.postDeviceCommands =
''
# Using acpi_pm as a clock source causes the guest clock to
@@ -98,7 +103,7 @@ let kernel = config.boot.kernelPackages.kernel; in
networking.usePredictableInterfaceNames = false;
# Make it easy to log in as root when running the test interactively.
- security.initialRootPassword = mkDefault "";
+ users.extraUsers.root.initialHashedPassword = mkOverride 150 "";
};
diff --git a/nixos/modules/virtualisation/amazon-config.nix b/nixos/modules/virtualisation/amazon-config.nix
index e816ed2d183..809cdb4d108 100644
--- a/nixos/modules/virtualisation/amazon-config.nix
+++ b/nixos/modules/virtualisation/amazon-config.nix
@@ -1,5 +1,3 @@
-{ config, pkgs, modulesPath, ... }:
-
{
- imports = [ "${modulesPath}/virtualisation/amazon-image.nix" ];
+ imports = [ ];
}
diff --git a/nixos/modules/virtualisation/amazon-image.nix b/nixos/modules/virtualisation/amazon-image.nix
index e129e496fe3..600a29f31bc 100644
--- a/nixos/modules/virtualisation/amazon-image.nix
+++ b/nixos/modules/virtualisation/amazon-image.nix
@@ -7,17 +7,6 @@ in
{
imports = [ ../profiles/headless.nix ./ec2-data.nix ];
- options = {
- ec2 = {
- hvm = mkOption {
- default = false;
- description = ''
- Whether the EC2 instance is a HVM instance.
- '';
- };
- };
- };
-
config = {
system.build.amazonImage =
pkgs.vmTools.runInLinuxVM (
@@ -70,10 +59,10 @@ in
# Register the paths in the Nix database.
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
- chroot /mnt ${config.nix.package}/bin/nix-store --load-db
+ chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
# Create the system profile to allow nixos-rebuild to work.
- chroot /mnt ${config.nix.package}/bin/nix-env \
+ chroot /mnt ${config.nix.package}/bin/nix-env --option build-users-group "" \
-p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
# `nixos-rebuild' requires an /etc/NIXOS.
@@ -102,6 +91,10 @@ in
boot.initrd.kernelModules = [ "xen-blkfront" ];
boot.kernelModules = [ "xen-netfront" ];
+ # Prevent the nouveau kernel module from being loaded, as it
+ # interferes with the nvidia/nvidia-uvm modules needed for CUDA.
+ boot.blacklistedKernelModules = [ "nouveau" ];
+
# Generate a GRUB menu. Amazon's pv-grub uses this to boot our kernel/initrd.
boot.loader.grub.version = if cfg.hvm then 2 else 1;
boot.loader.grub.device = if cfg.hvm then "/dev/xvda" else "nodev";
@@ -172,7 +165,7 @@ in
boot.initrd.extraUtilsCommands =
''
# We need swapon in the initrd.
- cp --remove-destination ${pkgs.utillinux}/sbin/swapon $out/bin
+ copy_bin_and_libs ${pkgs.utillinux}/sbin/swapon
'';
# Don't put old configurations in the GRUB menu. The user has no
@@ -191,10 +184,5 @@ in
environment.systemPackages = [ pkgs.cryptsetup ];
boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
-
- # Prevent logging in as root without a password. This doesn't really matter,
- # since the only PAM services that allow logging in with a null
- # password are local ones that are inaccessible on EC2 machines.
- security.initialRootPassword = mkDefault "!";
};
}
diff --git a/nixos/modules/virtualisation/amazon-options.nix b/nixos/modules/virtualisation/amazon-options.nix
new file mode 100644
index 00000000000..34a50dcab16
--- /dev/null
+++ b/nixos/modules/virtualisation/amazon-options.nix
@@ -0,0 +1,16 @@
+{ config, lib, pkgs, ... }:
+{
+ options = {
+ ec2 = {
+ hvm = lib.mkOption {
+ default = false;
+ internal = true;
+ description = ''
+ Whether the EC2 instance is a HVM instance.
+ '';
+ };
+ };
+ };
+
+ config = {};
+}
diff --git a/nixos/modules/virtualisation/azure-config.nix b/nixos/modules/virtualisation/azure-config.nix
new file mode 100644
index 00000000000..5c9f18ef52a
--- /dev/null
+++ b/nixos/modules/virtualisation/azure-config.nix
@@ -0,0 +1,5 @@
+{ config, pkgs, modulesPath, ... }:
+
+{
+ imports = [ "${modulesPath}/virtualisation/azure-image.nix" ];
+}
diff --git a/nixos/modules/virtualisation/azure-image.nix b/nixos/modules/virtualisation/azure-image.nix
new file mode 100644
index 00000000000..ab5a9c51fa5
--- /dev/null
+++ b/nixos/modules/virtualisation/azure-image.nix
@@ -0,0 +1,164 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ diskSize = "4096";
+in
+{
+ imports = [ ../profiles/headless.nix ];
+
+ system.build.azureImage =
+ pkgs.vmTools.runInLinuxVM (
+ pkgs.runCommand "azure-image"
+ { preVM =
+ ''
+ mkdir $out
+ diskImage=$out/$diskImageBase
+
+ cyl=$(((${diskSize}*1024*1024)/(512*63*255)))
+ size=$(($cyl*255*63*512))
+ roundedsize=$((($size/(1024*1024)+1)*(1024*1024)))
+ ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage $roundedsize
+ mv closure xchg/
+ '';
+
+ postVM =
+ ''
+ echo Converting
+ mkdir -p $out
+ ${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vpc $diskImage $out/disk.vhd
+ rm $diskImage
+ '';
+ diskImageBase = "nixos-${config.system.nixosVersion}-${pkgs.stdenv.system}.raw";
+ buildInputs = [ pkgs.utillinux pkgs.perl ];
+ exportReferencesGraph =
+ [ "closure" config.system.build.toplevel ];
+ }
+ ''
+ # Create partition table
+ ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
+ ${pkgs.parted}/sbin/parted /dev/vda mkpart primary ext4 1 ${diskSize}M
+ ${pkgs.parted}/sbin/parted /dev/vda print
+ . /sys/class/block/vda1/uevent
+ mknod /dev/vda1 b $MAJOR $MINOR
+
+ # Create an empty filesystem and mount it.
+ ${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L nixos /dev/vda1
+ ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
+
+ mkdir /mnt
+ mount /dev/vda1 /mnt
+
+ # The initrd expects these directories to exist.
+ mkdir /mnt/dev /mnt/proc /mnt/sys
+
+ mount --bind /proc /mnt/proc
+ mount --bind /dev /mnt/dev
+ mount --bind /sys /mnt/sys
+
+ # Copy all paths in the closure to the filesystem.
+ storePaths=$(perl ${pkgs.pathsFromGraph} /tmp/xchg/closure)
+
+ mkdir -p /mnt/nix/store
+ echo "copying everything (will take a while)..."
+ cp -prd $storePaths /mnt/nix/store/
+
+ echo Register the paths in the Nix database.
+ printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
+ chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
+
+ echo Create the system profile to allow nixos-rebuild to work.
+ chroot /mnt ${config.nix.package}/bin/nix-env \
+ -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} --option build-users-group ""
+
+ echo nixos-rebuild requires an /etc/NIXOS.
+ mkdir -p /mnt/etc
+ touch /mnt/etc/NIXOS
+
+ echo switch-to-configuration requires a /bin/sh
+ mkdir -p /mnt/bin
+ ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
+
+ echo Install a configuration.nix.
+ mkdir -p /mnt/etc/nixos /mnt/boot/grub
+ cp ${./azure-config.nix} /mnt/etc/nixos/configuration.nix
+
+ echo Generate the GRUB menu.
+ ln -s vda /dev/sda
+ chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
+
+ echo Almost done
+ umount /mnt/proc /mnt/dev /mnt/sys
+ umount /mnt
+ ''
+ );
+
+ fileSystems."/".device = "/dev/disk/by-label/nixos";
+
+ # Azure metadata is available as a CD-ROM drive.
+ fileSystems."/metadata".device = "/dev/sr0";
+
+ boot.kernelParams = [ "console=ttyS0" "earlyprintk=ttyS0" "rootdelay=300" "panic=1" "boot.panic_on_fail" ];
+ boot.initrd.kernelModules = [ "hv_vmbus" "hv_netvsc" "hv_utils" "hv_storvsc" ];
+
+ # Generate a GRUB menu.
+ boot.loader.grub.device = "/dev/sda";
+ boot.loader.grub.version = 2;
+ boot.loader.grub.timeout = 0;
+
+ # Don't put old configurations in the GRUB menu. The user has no
+ # way to select them anyway.
+ boot.loader.grub.configurationLimit = 0;
+
+ # Allow root logins only using the SSH key that the user specified
+ # at instance creation time.
+ services.openssh.enable = true;
+ services.openssh.permitRootLogin = "without-password";
+
+ # Force getting the hostname from Azure
+ networking.hostName = mkDefault "";
+
+ # Always include cryptsetup so that NixOps can use it.
+ environment.systemPackages = [ pkgs.cryptsetup ];
+
+ systemd.services.fetch-ssh-keys =
+ { description = "Fetch host keys and authorized_keys for root user";
+
+ wantedBy = [ "sshd.service" ];
+ before = [ "sshd.service" ];
+ after = [ "local-fs.target" ];
+
+ path = [ pkgs.coreutils ];
+ script =
+ ''
+ eval "$(base64 --decode /metadata/CustomData.bin)"
+ if ! [ -z "$ssh_host_ecdsa_key" ]; then
+ echo "downloaded ssh_host_ecdsa_key"
+ echo "$ssh_host_ecdsa_key" > /etc/ssh/ssh_host_ecdsa_key
+ chmod 600 /etc/ssh/ssh_host_ecdsa_key
+ fi
+
+ if ! [ -z "$ssh_host_ecdsa_key_pub" ]; then
+ echo "downloaded ssh_host_ecdsa_key_pub"
+ echo "$ssh_host_ecdsa_key_pub" > /etc/ssh/ssh_host_ecdsa_key.pub
+ chmod 644 /etc/ssh/ssh_host_ecdsa_key.pub
+ fi
+
+ if ! [ -z "$ssh_root_auth_key" ]; then
+ echo "downloaded ssh_root_auth_key"
+ mkdir -m 0700 -p /root/.ssh
+ echo "$ssh_root_auth_key" > /root/.ssh/authorized_keys
+ chmod 600 /root/.ssh/authorized_keys
+ fi
+ '';
+ serviceConfig.Type = "oneshot";
+ serviceConfig.RemainAfterExit = true;
+ serviceConfig.StandardError = "journal+console";
+ serviceConfig.StandardOutput = "journal+console";
+ };
+
+ networking.usePredictableInterfaceNames = false;
+
+ #users.extraUsers.root.openssh.authorizedKeys.keys = [ (builtins.readFile ) ];
+
+}
diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix
index 35455f17779..da39dda8535 100644
--- a/nixos/modules/virtualisation/containers.nix
+++ b/nixos/modules/virtualisation/containers.nix
@@ -10,6 +10,7 @@ let
isExecutable = true;
src = ./nixos-container.pl;
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
+ su = "${pkgs.shadow.su}/bin/su";
inherit (pkgs) utillinux;
};
@@ -54,6 +55,14 @@ in
'';
};
+ boot.enableContainers = mkOption {
+ type = types.bool;
+ default = !config.boot.isContainer;
+ description = ''
+ Whether to enable support for nixos containers.
+ '';
+ };
+
containers = mkOption {
type = types.attrsOf (types.submodule (
{ config, options, name, ... }:
@@ -111,6 +120,13 @@ in
'';
};
+ autoStart = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Wether the container is automatically started at boot-time.
+ '';
+ };
};
config = mkMerge
@@ -157,7 +173,7 @@ in
};
- config = mkIf (!config.boot.isContainer) {
+ config = mkIf (config.boot.enableContainers) {
systemd.services."container@" =
{ description = "Container '%i'";
@@ -187,7 +203,7 @@ in
script =
''
mkdir -p -m 0755 "$root/etc" "$root/var/lib"
- mkdir -p -m 0700 "$root/var/lib/private"
+ mkdir -p -m 0700 "$root/var/lib/private" "$root/root" /run/containers
if ! [ -e "$root/etc/os-release" ]; then
touch "$root/etc/os-release"
fi
@@ -196,7 +212,7 @@ in
"/nix/var/nix/profiles/per-container/$INSTANCE" \
"/nix/var/nix/gcroots/per-container/$INSTANCE"
- cp -f /etc/resolv.conf "$root/etc/resolv.conf"
+ cp --remove-destination /etc/resolv.conf "$root/etc/resolv.conf"
if [ "$PRIVATE_NETWORK" = 1 ]; then
extraFlags+=" --network-veth"
@@ -246,16 +262,20 @@ in
fi
fi
- # This blocks until the container-startup-done service
- # writes something to this pipe. FIXME: it also hangs
- # until the start timeout expires if systemd-nspawn exits.
- read x < $root/var/lib/startup-done
- rm -f $root/var/lib/startup-done
+ # Get the leader PID so that we can signal it in
+ # preStop. We can't use machinectl there because D-Bus
+ # might be shutting down. FIXME: in systemd 219 we can
+ # just signal systemd-nspawn to do a clean shutdown.
+ machinectl show "$INSTANCE" | sed 's/Leader=\(.*\)/\1/;t;d' > "/run/containers/$INSTANCE.pid"
'';
preStop =
''
- machinectl poweroff "$INSTANCE" || true
+ pid="$(cat /run/containers/$INSTANCE.pid)"
+ if [ -n "$pid" ]; then
+ kill -RTMIN+4 "$pid"
+ fi
+ rm -f "/run/containers/$INSTANCE.pid"
'';
restartIfChanged = false;
@@ -277,9 +297,12 @@ in
NotifyAccess = "all";
- # Note that on reboot, systemd-nspawn returns 10, so this
+ # Note that on reboot, systemd-nspawn returns 133, so this
# unit will be restarted. On poweroff, it returns 0, so the
# unit won't be restarted.
+ RestartForceExitStatus = "133";
+ SuccessExitStatus = "133";
+
Restart = "on-failure";
# Hack: we don't want to kill systemd-nspawn, since we call
@@ -308,11 +331,12 @@ in
LOCAL_ADDRESS=${cfg.localAddress}
''}
''}
+ ${optionalString cfg.autoStart ''
+ AUTO_START=1
+ ''}
'';
}) config.containers;
- # FIXME: auto-start containers.
-
# Generate /etc/hosts entries for the containers.
networking.extraHosts = concatStrings (mapAttrsToList (name: cfg: optionalString (cfg.localAddress != null)
''
diff --git a/nixos/modules/virtualisation/docker-image.nix b/nixos/modules/virtualisation/docker-image.nix
new file mode 100644
index 00000000000..0195ca5c6dc
--- /dev/null
+++ b/nixos/modules/virtualisation/docker-image.nix
@@ -0,0 +1,19 @@
+{ config, pkgs, ... }:
+
+{
+ imports = [
+ ../profiles/container.nix
+ ];
+
+ boot.postBootCommands =
+ ''
+ # Set virtualisation to docker
+ echo "docker" > /run/systemd/container
+ '';
+
+ # Iptables do not work in Docker.
+ networking.firewall.enable = false;
+
+ # Socket activated ssh presents problem in Docker.
+ services.openssh.startWhenNeeded = false;
+}
diff --git a/nixos/modules/virtualisation/docker.nix b/nixos/modules/virtualisation/docker.nix
index a0aa6135326..5be76b2682f 100644
--- a/nixos/modules/virtualisation/docker.nix
+++ b/nixos/modules/virtualisation/docker.nix
@@ -7,6 +7,8 @@ with lib;
let
cfg = config.virtualisation.docker;
+ pro = config.networking.proxy.default;
+ proxy_env = optionalAttrs (pro != null) { Environment = "\"http_proxy=${pro}\""; };
in
@@ -59,6 +61,7 @@ in
config = mkIf cfg.enable (mkMerge [
{ environment.systemPackages = [ pkgs.docker ];
+ users.extraGroups.docker.gid = config.ids.gids.docker;
}
(mkIf cfg.socketActivation {
@@ -72,7 +75,7 @@ in
# goes in config bundled with docker itself
LimitNOFILE = 1048576;
LimitNPROC = 1048576;
- };
+ } // proxy_env;
};
systemd.sockets.docker = {
@@ -98,7 +101,13 @@ in
# goes in config bundled with docker itself
LimitNOFILE = 1048576;
LimitNPROC = 1048576;
- };
+ } // proxy_env;
+
+ postStart = ''
+ while ! [ -e /var/run/docker.sock ]; do
+ sleep 0.1
+ done
+ '';
# Presumably some containers are running we don't want to interrupt
restartIfChanged = false;
diff --git a/nixos/modules/virtualisation/ec2-data.nix b/nixos/modules/virtualisation/ec2-data.nix
index 93a83a3e42a..15114b1e76a 100644
--- a/nixos/modules/virtualisation/ec2-data.nix
+++ b/nixos/modules/virtualisation/ec2-data.nix
@@ -44,7 +44,7 @@ with lib;
# into the image (a Nova feature).
if ! [ -e /root/.ssh/authorized_keys ]; then
echo "obtaining SSH key..."
- mkdir -p /root/.ssh
+ mkdir -m 0700 -p /root/.ssh
$wget http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key > /root/key.pub
if [ $? -eq 0 -a -e /root/key.pub ]; then
if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then
diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix
index 697423ac60b..ee5485071a3 100644
--- a/nixos/modules/virtualisation/google-compute-image.nix
+++ b/nixos/modules/virtualisation/google-compute-image.nix
@@ -7,6 +7,9 @@ in
{
imports = [ ../profiles/headless.nix ../profiles/qemu-guest.nix ];
+ # https://cloud.google.com/compute/docs/tutorials/building-images
+ networking.firewall.enable = mkDefault false;
+
system.build.googleComputeImage =
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "google-compute-image"
@@ -63,11 +66,12 @@ in
# Register the paths in the Nix database.
printRegistration=1 perl ${pkgs.pathsFromGraph} /tmp/xchg/closure | \
- chroot /mnt ${config.nix.package}/bin/nix-store --load-db
+ chroot /mnt ${config.nix.package}/bin/nix-store --load-db --option build-users-group ""
# Create the system profile to allow nixos-rebuild to work.
chroot /mnt ${config.nix.package}/bin/nix-env \
- -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel}
+ -p /nix/var/nix/profiles/system --set ${config.system.build.toplevel} \
+ --option build-users-group ""
# `nixos-rebuild' requires an /etc/NIXOS.
mkdir -p /mnt/etc
@@ -94,6 +98,7 @@ in
boot.kernelParams = [ "console=ttyS0" "panic=1" "boot.panic_on_fail" ];
boot.initrd.kernelModules = [ "virtio_scsi" ];
+ boot.kernelModules = [ "virtio_pci" "virtio_net" ];
# Generate a GRUB menu. Amazon's pv-grub uses this to boot our kernel/initrd.
boot.loader.grub.device = "/dev/sda";
@@ -107,6 +112,7 @@ in
# at instance creation time.
services.openssh.enable = true;
services.openssh.permitRootLogin = "without-password";
+ services.openssh.passwordAuthentication = mkDefault false;
# Force getting the hostname from Google Compute.
networking.hostName = mkDefault "";
@@ -119,6 +125,8 @@ in
169.254.169.254 metadata.google.internal metadata
'';
+ services.ntp.servers = [ "metadata.google.internal" ];
+
networking.usePredictableInterfaceNames = false;
systemd.services.fetch-ssh-keys =
@@ -126,18 +134,18 @@ in
wantedBy = [ "sshd.service" ];
before = [ "sshd.service" ];
- after = [ "network-online.target" ];
- wants = [ "network-online.target" ];
+ after = [ "network-online.target" "ip-up.target" ];
+ wants = [ "network-online.target" "ip-up.target" ];
- path = [ pkgs.wget ];
- script =
+ script = let wget = "${pkgs.wget}/bin/wget --retry-connrefused -t 15 --waitretry=10 --header='Metadata-Flavor: Google'"; in
''
- wget="wget --retry-connrefused -t 6 --waitretry=10"
+ # When dealing with cryptographic keys, we want to keep things private.
+ umask 077
# Don't download the SSH key if it has already been downloaded
if ! [ -e /root/.ssh/authorized_keys ]; then
echo "obtaining SSH key..."
- mkdir -p /root/.ssh
- $wget -O /root/authorized-keys-metadata http://metadata/0.1/meta-data/authorized-keys
+ mkdir -m 0700 -p /root/.ssh
+ ${wget} -O /root/authorized-keys-metadata http://metadata.google.internal/0.1/meta-data/authorized-keys
if [ $? -eq 0 -a -e /root/authorized-keys-metadata ]; then
cat /root/authorized-keys-metadata | cut -d: -f2- > /root/key.pub
if ! grep -q -f /root/key.pub /root/.ssh/authorized_keys; then
@@ -145,29 +153,109 @@ in
echo "new key added to authorized_keys"
fi
chmod 600 /root/.ssh/authorized_keys
- rm -f /root/key.pub /root/authorized-keys-metadata
fi
+ rm -f /root/key.pub /root/authorized-keys-metadata
fi
- echo "obtaining SSH private host key..."
- $wget -O /root/ssh_host_ecdsa_key http://metadata/0.1/meta-data/attributes/ssh_host_ecdsa_key
- if [ $? -eq 0 -a -e /root/ssh_host_ecdsa_key ]; then
- mv -f /root/ssh_host_ecdsa_key /etc/ssh/ssh_host_ecdsa_key
- echo "downloaded ssh_host_ecdsa_key"
- chmod 600 /etc/ssh/ssh_host_ecdsa_key
- fi
+ countKeys=0
+ ${flip concatMapStrings config.services.openssh.hostKeys (k :
+ let kName = baseNameOf k.path; in ''
+ echo "trying to obtain SSH private host key ${kName}"
+ ${wget} -O /root/${kName} http://metadata.google.internal/0.1/meta-data/attributes/${kName} && :
+ if [ $? -eq 0 -a -e /root/${kName} ]; then
+ countKeys=$((countKeys+1))
+ mv -f /root/${kName} ${k.path}
+ echo "downloaded ${k.path}"
+ chmod 600 ${k.path}
+ ${config.programs.ssh.package}/bin/ssh-keygen -y -f ${k.path} > ${k.path}.pub
+ chmod 644 ${k.path}.pub
+ fi
+ rm -f /root/${kName}
+ ''
+ )}
- echo "obtaining SSH public host key..."
- $wget -O /root/ssh_host_ecdsa_key.pub http://metadata/0.1/meta-data/attributes/ssh_host_ecdsa_key_pub
- if [ $? -eq 0 -a -e /root/ssh_host_ecdsa_key.pub ]; then
- mv -f /root/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_ecdsa_key.pub
- echo "downloaded ssh_host_ecdsa_key.pub"
- chmod 644 /etc/ssh/ssh_host_ecdsa_key.pub
+ if [[ $countKeys -le 0 ]]; then
+ echo "failed to obtain any SSH private host keys."
+ false
fi
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
serviceConfig.StandardError = "journal+console";
serviceConfig.StandardOutput = "journal+console";
- };
+ };
+
+ # Setings taken from https://cloud.google.com/compute/docs/tutorials/building-images#providedkernel
+ boot.kernel.sysctl = {
+ # enables syn flood protection
+ "net.ipv4.tcp_syncookies" = mkDefault "1";
+
+ # ignores source-routed packets
+ "net.ipv4.conf.all.accept_source_route" = mkDefault "0";
+
+ # ignores source-routed packets
+ "net.ipv4.conf.default.accept_source_route" = mkDefault "0";
+
+ # ignores ICMP redirects
+ "net.ipv4.conf.all.accept_redirects" = mkDefault "0";
+
+ # ignores ICMP redirects
+ "net.ipv4.conf.default.accept_redirects" = mkDefault "0";
+
+ # ignores ICMP redirects from non-GW hosts
+ "net.ipv4.conf.all.secure_redirects" = mkDefault "1";
+
+ # ignores ICMP redirects from non-GW hosts
+ "net.ipv4.conf.default.secure_redirects" = mkDefault "1";
+
+ # don't allow traffic between networks or act as a router
+ "net.ipv4.ip_forward" = mkDefault "0";
+
+ # don't allow traffic between networks or act as a router
+ "net.ipv4.conf.all.send_redirects" = mkDefault "0";
+
+ # don't allow traffic between networks or act as a router
+ "net.ipv4.conf.default.send_redirects" = mkDefault "0";
+
+ # reverse path filtering - IP spoofing protection
+ "net.ipv4.conf.all.rp_filter" = mkDefault "1";
+
+ # reverse path filtering - IP spoofing protection
+ "net.ipv4.conf.default.rp_filter" = mkDefault "1";
+
+ # ignores ICMP broadcasts to avoid participating in Smurf attacks
+ "net.ipv4.icmp_echo_ignore_broadcasts" = mkDefault "1";
+
+ # ignores bad ICMP errors
+ "net.ipv4.icmp_ignore_bogus_error_responses" = mkDefault "1";
+
+ # logs spoofed, source-routed, and redirect packets
+ "net.ipv4.conf.all.log_martians" = mkDefault "1";
+
+ # log spoofed, source-routed, and redirect packets
+ "net.ipv4.conf.default.log_martians" = mkDefault "1";
+
+ # implements RFC 1337 fix
+ "net.ipv4.tcp_rfc1337" = mkDefault "1";
+
+ # randomizes addresses of mmap base, heap, stack and VDSO page
+ "kernel.randomize_va_space" = mkDefault "2";
+
+ # provides protection from ToCToU races
+ "fs.protected_hardlinks" = mkDefault "1";
+
+ # provides protection from ToCToU races
+ "fs.protected_symlinks" = mkDefault "1";
+
+ # makes locating kernel addresses more difficult
+ "kernel.kptr_restrict" = mkDefault "1";
+
+ # set ptrace protections
+ "kernel.yama.ptrace_scope" = mkDefault "1";
+
+ # set perf only available to root
+ "kernel.perf_event_paranoid" = mkDefault "2";
+
+ };
+
}
diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix
index d7d700d8841..7410609e064 100644
--- a/nixos/modules/virtualisation/libvirtd.nix
+++ b/nixos/modules/virtualisation/libvirtd.nix
@@ -7,6 +7,7 @@ with lib;
let
cfg = config.virtualisation.libvirtd;
+ vswitch = config.virtualisation.vswitch;
configFile = pkgs.writeText "libvirtd.conf" ''
unix_sock_group = "libvirtd"
unix_sock_rw_perms = "0770"
@@ -56,6 +57,20 @@ in
'';
};
+ virtualisation.libvirtd.onShutdown =
+ mkOption {
+ type = types.enum ["shutdown" "suspend" ];
+ default = "suspend";
+ description =
+ ''
+ When shutting down / restarting the host what method should
+ be used to gracefully halt the guests. Setting to "shutdown"
+ will cause an ACPI shutdown of each guest. "suspend" will
+ attempt to save the state of the guests ready to restore on boot.
+ '';
+ };
+
+
};
@@ -73,12 +88,17 @@ in
{ description = "Libvirt Virtual Machine Management Daemon";
wantedBy = [ "multi-user.target" ];
- after = [ "systemd-udev-settle.service" ];
+ after = [ "systemd-udev-settle.service" ]
+ ++ optional vswitch.enable "vswitchd.service";
- path =
- [ pkgs.bridge_utils pkgs.dmidecode pkgs.dnsmasq
+ path = [
+ pkgs.bridge-utils
+ pkgs.dmidecode
+ pkgs.dnsmasq
pkgs.ebtables
- ] ++ optional cfg.enableKVM pkgs.qemu_kvm;
+ ]
+ ++ optional cfg.enableKVM pkgs.qemu_kvm
+ ++ optional vswitch.enable vswitch.package;
preStart =
''
@@ -109,12 +129,12 @@ in
# config file. But this path can unfortunately be garbage collected
# while still being used by the virtual machine. So update the
# emulator path on each startup to something valid (re-scan $PATH).
- for file in /etc/libvirt/qemu/*.xml; do
+ for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do
test -f "$file" || continue
# get (old) emulator path from config file
emulator=$(grep "^[[:space:]]*" "$file" | sed 's,^[[:space:]]*\(.*\) .*,\1,')
# get a (definitely) working emulator path by re-scanning $PATH
- new_emulator=$(command -v $(basename "$emulator"))
+ new_emulator=$(PATH=${pkgs.libvirt}/libexec:$PATH command -v $(basename "$emulator"))
# write back
sed -i "s,^[[:space:]]*.*, $new_emulator ," "$file"
done
@@ -152,7 +172,12 @@ in
${pkgs.libvirt}/etc/rc.d/init.d/libvirt-guests start || true
'';
- postStop = "${pkgs.libvirt}/etc/rc.d/init.d/libvirt-guests stop";
+ postStop =
+ ''
+ export PATH=${pkgs.gettext}/bin:$PATH
+ export ON_SHUTDOWN=${cfg.onShutdown}
+ ${pkgs.libvirt}/etc/rc.d/init.d/libvirt-guests stop
+ '';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
diff --git a/nixos/modules/virtualisation/lxc-container.nix b/nixos/modules/virtualisation/lxc-container.nix
new file mode 100644
index 00000000000..2fa749d542e
--- /dev/null
+++ b/nixos/modules/virtualisation/lxc-container.nix
@@ -0,0 +1,26 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+{
+ imports = [
+ ../profiles/container.nix
+ ];
+
+ # Allow the user to login as root without password.
+ users.extraUsers.root.initialHashedPassword = mkOverride 150 "";
+
+ # Some more help text.
+ services.mingetty.helpLine =
+ ''
+
+ Log in as "root" with an empty password.
+ '';
+
+ # Containers should be light-weight, so start sshd on demand.
+ services.openssh.enable = mkDefault true;
+ services.openssh.startWhenNeeded = mkDefault true;
+
+ # Allow ssh connections
+ networking.firewall.allowedTCPPorts = [ 22 ];
+}
diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix
new file mode 100644
index 00000000000..22da012e414
--- /dev/null
+++ b/nixos/modules/virtualisation/lxc.nix
@@ -0,0 +1,80 @@
+# LXC Configuration
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.virtualisation.lxc;
+
+in
+
+{
+ ###### interface
+
+ options.virtualisation.lxc = {
+ enable =
+ mkOption {
+ type = types.bool;
+ default = false;
+ description =
+ ''
+ This enables Linux Containers (LXC), which provides tools
+ for creating and managing system or application containers
+ on Linux.
+ '';
+ };
+
+ systemConfig =
+ mkOption {
+ type = types.lines;
+ default = "";
+ description =
+ ''
+ This is the system-wide LXC config. See
+ lxc.system.conf
+ 5 .
+ '';
+ };
+
+ defaultConfig =
+ mkOption {
+ type = types.lines;
+ default = "";
+ description =
+ ''
+ Default config (default.conf) for new containers, i.e. for
+ network config. See lxc.container.conf
+ 5 .
+ '';
+ };
+
+ usernetConfig =
+ mkOption {
+ type = types.lines;
+ default = "";
+ description =
+ ''
+ This is the config file for managing unprivileged user network
+ administration access in LXC. See
+ lxc-user-net 5
+ .
+ '';
+ };
+
+ };
+
+ ###### implementation
+
+ config = mkIf cfg.enable {
+
+ environment.systemPackages = [ pkgs.lxc ];
+
+ environment.etc."lxc/lxc.conf".text = cfg.systemConfig;
+ environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig;
+ environment.etc."lxc/default.conf".text = cfg.defaultConfig;
+
+ };
+
+}
diff --git a/nixos/modules/virtualisation/nixos-container.pl b/nixos/modules/virtualisation/nixos-container.pl
index 7403a42f0f1..f1d9e64ee38 100644
--- a/nixos/modules/virtualisation/nixos-container.pl
+++ b/nixos/modules/virtualisation/nixos-container.pl
@@ -8,6 +8,7 @@ use Fcntl ':flock';
use Getopt::Long qw(:config gnu_getopt);
my $nsenter = "@utillinux@/bin/nsenter";
+my $su = "@su@";
# Ensure a consistent umask.
umask 0022;
@@ -22,6 +23,7 @@ Usage: nixos-container list
nixos-container start
nixos-container stop
nixos-container status
+ nixos-container update [--config ]
nixos-container login
nixos-container root-login
nixos-container run -- args...
@@ -104,6 +106,10 @@ if ($action eq "create") {
die "$0: container ‘$containerName’ already exists\n" if -e $confFile;
+ # Due to interface name length restrictions, container names must
+ # be restricted too.
+ die "$0: container name ‘$containerName’ is too long\n" if length $containerName > 11;
+
# Get an unused IP address.
my %usedIPs;
foreach my $confFile2 (glob "/etc/containers/*.conf") {
@@ -201,15 +207,32 @@ sub runInContainer {
die "cannot run ‘nsenter’: $!\n";
}
+# Remove a directory while recursively unmounting all mounted filesystems within
+# that directory and unmounting/removing that directory afterwards as well.
+#
+# NOTE: If the specified path is a mountpoint, its contents will be removed,
+# only mountpoints underneath that path will be unmounted properly.
+sub safeRemoveTree {
+ my ($path) = @_;
+ system("find", $path, "-mindepth", "1", "-xdev",
+ "(", "-type", "d", "-exec", "mountpoint", "-q", "{}", ";", ")",
+ "-exec", "umount", "-fR", "{}", "+");
+ system("rm", "--one-file-system", "-rf", $path);
+ if (-e $path) {
+ system("umount", "-fR", $path);
+ system("rm", "--one-file-system", "-rf", $path);
+ }
+}
+
if ($action eq "destroy") {
die "$0: cannot destroy declarative container (remove it from your configuration.nix instead)\n"
unless POSIX::access($confFile, &POSIX::W_OK);
stopContainer if isContainerRunning;
- rmtree($profileDir) if -e $profileDir;
- rmtree($gcRootsDir) if -e $gcRootsDir;
- rmtree($root) if -e $root;
+ safeRemoveTree($profileDir) if -e $profileDir;
+ safeRemoveTree($gcRootsDir) if -e $gcRootsDir;
+ safeRemoveTree($root) if -e $root;
unlink($confFile) or die;
}
@@ -250,14 +273,14 @@ elsif ($action eq "login") {
}
elsif ($action eq "root-login") {
- runInContainer("su", "root", "-l");
+ runInContainer("@su@", "root", "-l");
}
elsif ($action eq "run") {
shift @ARGV; shift @ARGV;
# Escape command.
my $s = join(' ', map { s/'/'\\''/g; "'$_'" } @ARGV);
- runInContainer("su", "root", "-l", "-c", "exec " . $s);
+ runInContainer("@su@", "root", "-l", "-c", "exec " . $s);
}
elsif ($action eq "show-ip") {
diff --git a/nixos/modules/virtualisation/nova.nix b/nixos/modules/virtualisation/nova.nix
index 8795b5b52d5..21e060cf266 100644
--- a/nixos/modules/virtualisation/nova.nix
+++ b/nixos/modules/virtualisation/nova.nix
@@ -147,7 +147,7 @@ in
path =
[ pkgs.sudo pkgs.vlan pkgs.nettools pkgs.iptables pkgs.qemu_kvm
pkgs.e2fsprogs pkgs.utillinux pkgs.multipath_tools pkgs.iproute
- pkgs.bridge_utils
+ pkgs.bridge-utils
];
exec = "${nova}/bin/nova-compute --flagfile=${novaConf}";
@@ -163,7 +163,7 @@ in
path =
[ pkgs.sudo pkgs.vlan pkgs.dnsmasq pkgs.nettools pkgs.iptables
- pkgs.iproute pkgs.bridge_utils pkgs.radvd
+ pkgs.iproute pkgs.bridge-utils pkgs.radvd
];
exec = "${nova}/bin/nova-network --flagfile=${novaConf}";
diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix
new file mode 100644
index 00000000000..c1579d94657
--- /dev/null
+++ b/nixos/modules/virtualisation/openvswitch.nix
@@ -0,0 +1,117 @@
+# Systemd services for openvswitch
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.virtualisation.vswitch;
+
+in
+
+{
+
+ options = {
+
+ virtualisation.vswitch.enable = mkOption {
+ type = types.bool;
+ default = false;
+ description =
+ ''
+ Enable Open vSwitch. A configuration
+ daemon (ovs-server) will be started.
+ '';
+ };
+
+
+ virtualisation.vswitch.package = mkOption {
+ type = types.package;
+ default = pkgs.openvswitch;
+ description =
+ ''
+ Open vSwitch package to use.
+ '';
+ };
+
+ };
+
+ config = mkIf cfg.enable (let
+
+ # Where the communication sockets live
+ runDir = "/var/run/openvswitch";
+
+ # Where the config database live (can't be in nix-store)
+ stateDir = "/var/db/openvswitch";
+
+ # The path to the an initialized version of the database
+ db = pkgs.stdenv.mkDerivation {
+ name = "vswitch.db";
+ unpackPhase = "true";
+ buildPhase = "true";
+ buildInputs = with pkgs; [
+ cfg.package
+ ];
+ installPhase =
+ ''
+ ensureDir $out/
+ '';
+ };
+
+ in {
+
+ environment.systemPackages = [ cfg.package ];
+
+ boot.kernelModules = [ "tun" "openvswitch" ];
+
+ boot.extraModulePackages = [ cfg.package ];
+
+ systemd.services.ovsdb = {
+ description = "Open_vSwitch Database Server";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "systemd-udev-settle.service" ];
+ wants = [ "vswitchd.service" ];
+ path = [ cfg.package ];
+ restartTriggers = [ db cfg.package ];
+ # Create the config database
+ preStart =
+ ''
+ mkdir -p ${runDir}
+ mkdir -p /var/db/openvswitch
+ chmod +w /var/db/openvswitch
+ if [[ ! -e /var/db/openvswitch/conf.db ]]; then
+ ${cfg.package}/bin/ovsdb-tool create \
+ "/var/db/openvswitch/conf.db" \
+ "${cfg.package}/share/openvswitch/vswitch.ovsschema"
+ fi
+ chmod -R +w /var/db/openvswitch
+ '';
+ serviceConfig.ExecStart =
+ ''
+ ${cfg.package}/bin/ovsdb-server \
+ --remote=punix:${runDir}/db.sock \
+ --private-key=db:Open_vSwitch,SSL,private_key \
+ --certificate=db:Open_vSwitch,SSL,certificate \
+ --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \
+ --unixctl=ovsdb.ctl.sock \
+ /var/db/openvswitch/conf.db
+ '';
+ serviceConfig.Restart = "always";
+ serviceConfig.RestartSec = 3;
+ postStart =
+ ''
+ ${cfg.package}/bin/ovs-vsctl --timeout 3 --retry --no-wait init
+ '';
+
+ };
+
+ systemd.services.vswitchd = {
+ description = "Open_vSwitch Daemon";
+ bindsTo = [ "ovsdb.service" ];
+ after = [ "ovsdb.service" ];
+ path = [ cfg.package ];
+ serviceConfig.ExecStart = ''${cfg.package}/bin/ovs-vswitchd'';
+ };
+
+ });
+
+}
diff --git a/nixos/modules/virtualisation/parallels-guest.nix b/nixos/modules/virtualisation/parallels-guest.nix
new file mode 100644
index 00000000000..2f40283b3e1
--- /dev/null
+++ b/nixos/modules/virtualisation/parallels-guest.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, pkgs_i686, ... }:
+
+with lib;
+
+let
+
+ prl-tools = config.boot.kernelPackages.prl-tools;
+
+in
+
+{
+
+ options = {
+ hardware.parallels = {
+
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ This enables Parallel Tools for Linux guests, along with provided
+ video, mouse and other hardware drivers.
+ '';
+ };
+
+ };
+
+ };
+
+ config = mkIf config.hardware.parallels.enable {
+
+ services.xserver = {
+ drivers = singleton
+ { name = "prlvideo"; modules = [ prl-tools ]; libPath = [ prl-tools ]; };
+
+ screenSection = ''
+ Option "NoMTRR"
+ '';
+
+ config = ''
+ Section "InputClass"
+ Identifier "prlmouse"
+ MatchIsPointer "on"
+ MatchTag "prlmouse"
+ Driver "prlmouse"
+ EndSection
+ '';
+ };
+
+ hardware.opengl.package = prl-tools;
+ hardware.opengl.package32 = pkgs_i686.linuxPackages.prl-tools.override { libsOnly = true; kernel = null; };
+
+ services.udev.packages = [ prl-tools ];
+
+ environment.systemPackages = [ prl-tools ];
+
+ boot.extraModulePackages = [ prl-tools ];
+
+ boot.kernelModules = [ "prl_tg" "prl_eth" "prl_fs" "prl_fs_freeze" "acpi_memhotplug" ];
+
+ services.ntp.enable = false;
+
+ systemd.services.prltoolsd = {
+ description = "Parallels Tools' service";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${prl-tools}/bin/prltoolsd -f";
+ PIDFile = "/var/run/prltoolsd.pid";
+ };
+ };
+
+ systemd.services.prlfsmountd = {
+ description = "Parallels Shared Folders Daemon";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = rec {
+ ExecStart = "${prl-tools}/sbin/prlfsmountd ${PIDFile}";
+ ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p /media";
+ ExecStopPost = "${prl-tools}/sbin/prlfsmountd -u";
+ PIDFile = "/run/prlfsmountd.pid";
+ };
+ };
+
+ systemd.services.prlshprint = {
+ description = "Parallels Shared Printer Tool";
+ wantedBy = [ "multi-user.target" ];
+ bindsTo = [ "cups.service" ];
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${prl-tools}/bin/prlshprint";
+ };
+ };
+
+ };
+}
diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix
index 58386ce5cf5..8c7e840910d 100644
--- a/nixos/modules/virtualisation/qemu-vm.nix
+++ b/nixos/modules/virtualisation/qemu-vm.nix
@@ -36,13 +36,28 @@ let
${toString config.virtualisation.diskSize}M || exit 1
fi
- # Create a directory for exchanging data with the VM.
+ # Create a directory for storing temporary data of the running VM.
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
fi
- cd $TMPDIR
+ # Create a directory for exchanging data with the VM.
mkdir -p $TMPDIR/xchg
+ ${if cfg.useBootLoader then ''
+ # Create a writable copy/snapshot of the boot disk
+ # A writable boot disk can be booted from automatically
+ ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 -b ${bootDisk}/disk.img $TMPDIR/disk.img || exit 1
+
+ ${if cfg.useEFIBoot then ''
+ # VM needs a writable flash BIOS
+ cp ${bootDisk}/bios.bin $TMPDIR || exit 1
+ chmod 0644 $TMPDIR/bios.bin || exit 1
+ '' else ''
+ ''}
+ '' else ''
+ ''}
+
+ cd $TMPDIR
idx=2
extraDisks=""
${flip concatMapStrings cfg.emptyDiskImages (size: ''
@@ -52,20 +67,21 @@ let
'')}
# Start QEMU.
- # "-boot menu=on" is there, because I don't know how to make qemu boot from 2nd hd.
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \
-name ${vmName} \
-m ${toString config.virtualisation.memorySize} \
${optionalString (pkgs.stdenv.system == "x86_64-linux") "-cpu kvm64"} \
- -net nic,vlan=0,model=virtio \
- -net user,vlan=0''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} \
+ ${concatStringsSep " " config.virtualisation.qemu.networkingOptions} \
-virtfs local,path=/nix/store,security_model=none,mount_tag=store \
-virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
${if cfg.useBootLoader then ''
-drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
- -drive index=1,id=drive2,file=${bootDisk}/disk.img,if=virtio,readonly \
- -boot menu=on \
+ -drive index=1,id=drive2,file=$TMPDIR/disk.img,media=disk \
+ ${if cfg.useEFIBoot then ''
+ -pflash $TMPDIR/bios.bin \
+ '' else ''
+ ''}
'' else ''
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
-kernel ${config.system.build.toplevel}/kernel \
@@ -75,7 +91,8 @@ let
$extraDisks \
${qemuGraphics} \
${toString config.virtualisation.qemu.options} \
- $QEMU_OPTS
+ $QEMU_OPTS \
+ $@
'';
@@ -99,23 +116,44 @@ let
''
mkdir $out
diskImage=$out/disk.img
- ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "32M"
+ bootFlash=$out/bios.bin
+ ${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "40M"
+ ${if cfg.useEFIBoot then ''
+ cp ${pkgs.OVMF-CSM}/FV/OVMF.fd $bootFlash
+ chmod 0644 $bootFlash
+ '' else ''
+ ''}
'';
buildInputs = [ pkgs.utillinux ];
+ QEMU_OPTS = if cfg.useEFIBoot
+ then "-pflash $out/bios.bin -nographic -serial pty"
+ else "-nographic -serial pty";
}
''
- # Create a single /boot partition.
- ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
- ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
- . /sys/class/block/vda1/uevent
- mknod /dev/vda1 b $MAJOR $MINOR
+ # Create a /boot EFI partition with 40M
+ ${pkgs.gptfdisk}/sbin/sgdisk -G /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -A 1:set:1 /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -A 2:set:2 /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -h 2 /dev/vda
+ ${pkgs.gptfdisk}/sbin/sgdisk -C /dev/vda
+ ${pkgs.utillinux}/bin/sfdisk /dev/vda -A 2
+ . /sys/class/block/vda2/uevent
+ mknod /dev/vda2 b $MAJOR $MINOR
. /sys/class/block/vda/uevent
- ${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
- ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
+ ${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
+ export MTOOLS_SKIP_CHECK=1
+ ${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
- # Mount /boot.
+ # Mount /boot; load necessary modules first.
+ ${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_cp437.ko || true
+ ${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_iso8859-1.ko || true
+ ${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/fat.ko || true
+ ${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/vfat.ko || true
+ ${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/efivarfs/efivarfs.ko || true
mkdir /boot
- mount /dev/vda1 /boot
+ mount /dev/vda2 /boot
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
mkdir /boot/grub
@@ -248,12 +286,31 @@ in
description = "Primary IP address used in /etc/hosts.";
};
- virtualisation.qemu.options =
- mkOption {
- default = [];
- example = [ "-vga std" ];
- description = "Options passed to QEMU.";
- };
+ virtualisation.qemu = {
+ options =
+ mkOption {
+ default = [];
+ example = [ "-vga std" ];
+ description = "Options passed to QEMU.";
+ };
+
+ networkingOptions =
+ mkOption {
+ default = [
+ "-net nic,vlan=0,model=virtio"
+ "-net user,vlan=0\${QEMU_NET_OPTS:+,$QEMU_NET_OPTS}"
+ ];
+ type = types.listOf types.str;
+ description = ''
+ Networking-related command-line options that should be passed to qemu.
+ The default is to use userspace networking (slirp).
+
+ If you override this option, be advised to keep
+ ''${QEMU_NET_OPTS:+,$QEMU_NET_OPTS} (as seen in the default)
+ to keep the default runtime behaviour.
+ '';
+ };
+ };
virtualisation.useBootLoader =
mkOption {
@@ -269,6 +326,17 @@ in
'';
};
+ virtualisation.useEFIBoot =
+ mkOption {
+ default = false;
+ description =
+ ''
+ If enabled, the virtual machine will provide a EFI boot
+ manager.
+ useEFIBoot is ignored if useBootLoader == false.
+ '';
+ };
+
};
config = {
@@ -278,7 +346,7 @@ in
boot.initrd.extraUtilsCommands =
''
# We need mke2fs in the initrd.
- cp -f ${pkgs.e2fsprogs}/sbin/mke2fs $out/bin
+ copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/mke2fs
'';
boot.initrd.postDeviceCommands =
@@ -361,8 +429,8 @@ in
};
} // optionalAttrs cfg.useBootLoader
{ "/boot" =
- { device = "/dev/disk/by-label/boot";
- fsType = "ext4";
+ { device = "/dev/vdb2";
+ fsType = "vfat";
options = "ro";
noCheck = true; # fsck fails on a r/o filesystem
};
@@ -383,7 +451,7 @@ in
# When building a regular system configuration, override whatever
# video driver the host uses.
- services.xserver.videoDrivers = mkVMOverride [ "vesa" ];
+ services.xserver.videoDrivers = mkVMOverride [ "modesetting" ];
services.xserver.defaultDepth = mkVMOverride 0;
services.xserver.resolutions = mkVMOverride [ { x = 1024; y = 768; } ];
services.xserver.monitorSection =
@@ -395,6 +463,7 @@ in
# Wireless won't work in the VM.
networking.wireless.enable = mkVMOverride false;
+ networking.connman.enable = mkVMOverride false;
# Speed up booting by not waiting for ARP.
networking.dhcpcd.extraConfig = "noarp";
diff --git a/nixos/modules/virtualisation/virtualbox-guest.nix b/nixos/modules/virtualisation/virtualbox-guest.nix
index a5a4db79787..a0e4bd558e0 100644
--- a/nixos/modules/virtualisation/virtualbox-guest.nix
+++ b/nixos/modules/virtualisation/virtualbox-guest.nix
@@ -6,7 +6,7 @@ with lib;
let
- cfg = config.services.virtualbox;
+ cfg = config.services.virtualboxGuest;
kernel = config.boot.kernelPackages;
in
@@ -17,7 +17,7 @@ in
options = {
- services.virtualbox = {
+ services.virtualboxGuest = {
enable = mkOption {
default = false;
diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix
index 106b269d9e1..8232f6e50df 100644
--- a/nixos/modules/virtualisation/virtualbox-image.nix
+++ b/nixos/modules/virtualisation/virtualbox-image.nix
@@ -128,6 +128,6 @@ in {
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/sda";
- services.virtualbox.enable = true;
+ services.virtualboxGuest.enable = true;
};
}
diff --git a/nixos/modules/virtualisation/xen-dom0.nix b/nixos/modules/virtualisation/xen-dom0.nix
index 566059472c9..ea9f61aad6a 100644
--- a/nixos/modules/virtualisation/xen-dom0.nix
+++ b/nixos/modules/virtualisation/xen-dom0.nix
@@ -5,18 +5,8 @@
with lib;
let
-
cfg = config.virtualisation.xen;
-
xen = pkgs.xen;
-
- xendConfig = pkgs.writeText "xend-config.sxp"
- ''
- (loglevel DEBUG)
- (network-script network-bridge)
- (vif-script vif-bridge)
- '';
-
in
{
@@ -58,23 +48,62 @@ in
'';
};
+ virtualisation.xen.bridge =
+ mkOption {
+ default = "xenbr0";
+ description =
+ ''
+ Create a bridge for the Xen domUs to connect to.
+ '';
+ };
+
+ virtualisation.xen.stored =
+ mkOption {
+ type = types.path;
+ description =
+ ''
+ Xen Store daemon to use. Defaults to oxenstored of the xen package.
+ '';
+ };
+
+ virtualisation.xen.trace =
+ mkOption {
+ default = false;
+ description =
+ ''
+ Enable Xen tracing.
+ '';
+ };
};
###### implementation
config = mkIf cfg.enable {
+ assertions = [ {
+ assertion = pkgs.stdenv.isx86_64;
+ message = "Xen currently not supported on ${pkgs.stdenv.system}";
+ } {
+ assertion = config.boot.loader.grub.enable && (config.boot.loader.grub.efiSupport == false);
+ message = "Xen currently does not support EFI boot";
+ } ];
+
+ virtualisation.xen.stored = mkDefault "${xen}/bin/oxenstored";
environment.systemPackages = [ xen ];
- # Domain 0 requires a pvops-enabled kernel.
- boot.kernelPackages = pkgs.linuxPackages_3_2_xen;
+ # Make sure Domain 0 gets the required configuration
+ #boot.kernelPackages = pkgs.boot.kernelPackages.override { features={xen_dom0=true;}; };
boot.kernelModules =
- [ "xen_evtchn" "xen_gntdev" "xen_blkback" "xen_netback" "xen_pciback"
- "blktap" "tun"
+ [ "xen-evtchn" "xen-gntdev" "xen-gntalloc" "xen-blkback" "xen-netback"
+ "xen-pciback" "evtchn" "gntdev" "netbk" "blkbk" "xen-scsibk"
+ "usbbk" "pciback" "xen-acpi-processor" "blktap2" "tun" "netxen_nic"
+ "xen_wdt" "xen-acpi-processor" "xen-privcmd" "xen-scsiback"
+ "xenfs"
];
+
# The radeonfb kernel module causes the screen to go black as soon
# as it's loaded, so don't load it.
boot.blacklistedKernelModules = [ "radeonfb" ];
@@ -87,8 +116,8 @@ in
options loop max_loop=64
'';
- virtualisation.xen.bootParams =
- [ "loglvl=all" "guest_loglvl=all" ] ++
+ virtualisation.xen.bootParams = [] ++
+ optionals cfg.trace [ "loglvl=all" "guest_loglvl=all" ] ++
optional (cfg.domain0MemorySize != 0) "dom0_mem=${toString cfg.domain0MemorySize}M";
system.extraSystemBuilderCmds =
@@ -101,78 +130,162 @@ in
system.activationScripts.xen =
''
if [ -d /proc/xen ]; then
- ${pkgs.sysvtools}/bin/mountpoint -q /proc/xen || \
+ ${pkgs.kmod}/bin/modprobe xenfs 2> /dev/null
+ ${pkgs.utillinux}/bin/mountpoint -q /proc/xen || \
${pkgs.utillinux}/bin/mount -t xenfs none /proc/xen
fi
'';
- jobs.xend =
- { description = "Xen Control Daemon";
+ # Domain 0 requires a pvops-enabled kernel.
+ system.requiredKernelConfig = with config.lib.kernelConfig;
+ [ (isYes "XEN")
+ (isYes "X86_IO_APIC")
+ (isYes "ACPI")
+ (isYes "XEN_DOM0")
+ (isYes "PCI_XEN")
+ (isYes "XEN_DEV_EVTCHN")
+ (isYes "XENFS")
+ (isYes "XEN_COMPAT_XENFS")
+ (isYes "XEN_SYS_HYPERVISOR")
+ (isYes "XEN_GNTDEV")
+ (isYes "XEN_BACKEND")
+ (isModule "XEN_NETDEV_BACKEND")
+ (isModule "XEN_BLKDEV_BACKEND")
+ (isModule "XEN_PCIDEV_BACKEND")
+ (isYes "XEN_BALLOON")
+ (isYes "XEN_SCRUB_PAGES")
+ ];
- startOn = "stopped udevtrigger";
-
- path =
- [ pkgs.bridge_utils pkgs.gawk pkgs.iproute pkgs.nettools
- pkgs.utillinux pkgs.bash xen pkgs.pciutils pkgs.procps
- ];
-
- environment.XENCONSOLED_TRACE = "hv";
-
- preStart =
- ''
- mkdir -p /var/log/xen/console -m 0700
-
- ${xen}/sbin/xend start
-
- # Wait until Xend is running.
- for ((i = 0; i < 60; i++)); do echo "waiting for xend..."; ${xen}/sbin/xend status && break; done
-
- ${xen}/sbin/xend status || exit 1
- '';
-
- postStop = "${xen}/sbin/xend stop";
- };
-
- jobs.xendomains =
- { description = "Automatically starts, saves and restores Xen domains on startup/shutdown";
-
- startOn = "started xend";
-
- stopOn = "starting shutdown and stopping xend";
-
- restartIfChanged = false;
-
- path = [ pkgs.xen ];
-
- environment.XENDOM_CONFIG = "${xen}/etc/sysconfig/xendomains";
-
- preStart =
- ''
- mkdir -p /var/lock/subsys -m 755
- ${xen}/etc/init.d/xendomains start
- '';
-
- postStop = "${xen}/etc/init.d/xendomains stop";
- };
-
- # To prevent a race between dhcpcd and xend's bridge setup script
- # (which renames eth* to peth* and recreates eth* as a virtual
- # device), start dhcpcd after xend.
- jobs.dhcpcd.startOn = mkOverride 50 "started xend";
environment.etc =
- [ { source = xendConfig;
- target = "xen/xend-config.sxp";
- }
- { source = "${xen}/etc/xen/scripts";
- target = "xen/scripts";
+ [ { source = "${xen}/etc/xen/xl.conf";
+ target = "xen/xl.conf";
}
];
# Xen provides udev rules.
services.udev.packages = [ xen ];
- services.udev.path = [ pkgs.bridge_utils pkgs.iproute ];
+ services.udev.path = [ pkgs.bridge-utils pkgs.iproute ];
+
+ systemd.services.xen-store = {
+ description = "Xen Store Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network.target" "xen-store.socket" ];
+ requires = [ "xen-store.socket" ];
+ preStart = ''
+ export XENSTORED_ROOTDIR="/var/lib/xenstored"
+ rm -f "$XENSTORED_ROOTDIR"/tdb* &>/dev/null
+
+ mkdir -p /var/run
+ ${optionalString cfg.trace "mkdir -p /var/log/xen"}
+ grep -q control_d /proc/xen/capabilities
+ '';
+ serviceConfig.ExecStart = ''
+ ${cfg.stored}${optionalString cfg.trace " -T /var/log/xen/xenstored-trace.log"} --no-fork
+ '';
+ postStart = ''
+ time=0
+ timeout=30
+ # Wait for xenstored to actually come up, timing out after 30 seconds
+ while [ $time -lt $timeout ] && ! `${pkgs.xen}/bin/xenstore-read -s / >/dev/null 2>&1` ; do
+ time=$(($time+1))
+ sleep 1
+ done
+
+ # Exit if we timed out
+ if ! [ $time -lt $timeout ] ; then
+ echo "Could not start Xenstore Daemon"
+ exit 1
+ fi
+
+ ${pkgs.xen}/bin/xenstore-write "/local/domain/0/name" "Domain-0"
+ ${pkgs.xen}/bin/xenstore-write "/local/domain/0/domid" 0
+ '';
+ };
+
+ systemd.sockets.xen-store = {
+ description = "XenStore Socket for userspace API";
+ wantedBy = [ "sockets.target" ];
+ socketConfig = {
+ ListenStream = [ "/var/run/xenstored/socket" "/var/run/xenstored/socket_ro" ];
+ SocketMode = "0660";
+ SocketUser = "root";
+ SocketGroup = "root";
+ };
+ };
+
+
+ systemd.services.xen-console = {
+ description = "Xen Console Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "xen-store.service" ];
+ preStart = ''
+ mkdir -p /var/run/xen
+ ${optionalString cfg.trace "mkdir -p /var/log/xen"}
+ grep -q control_d /proc/xen/capabilities
+ '';
+ serviceConfig = {
+ ExecStart = ''
+ ${pkgs.xen}/bin/xenconsoled${optionalString cfg.trace " --log=all --log-dir=/var/log/xen"}
+ '';
+ };
+ };
+
+
+ systemd.services.xen-qemu = {
+ description = "Xen Qemu Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "xen-console.service" ];
+ serviceConfig.ExecStart = ''
+ ${pkgs.xen}/lib/xen/bin/qemu-system-i386 -xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv \
+ -monitor /dev/null -serial /dev/null -parallel /dev/null
+ '';
+ };
+
+
+ systemd.services.xen-watchdog = {
+ description = "Xen Watchdog Daemon";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "xen-qemu.service" ];
+ serviceConfig.ExecStart = "${pkgs.xen}/bin/xenwatchdogd 30 15";
+ serviceConfig.Type = "forking";
+ serviceConfig.RestartSec = "1";
+ serviceConfig.Restart = "on-failure";
+ };
+
+
+ systemd.services.xen-bridge = {
+ description = "Xen bridge";
+ wantedBy = [ "multi-user.target" ];
+ before = [ "xen-domains.service" ];
+ serviceConfig.RemainAfterExit = "yes";
+ serviceConfig.ExecStart = ''
+ ${pkgs.bridge-utils}/bin/brctl addbr ${cfg.bridge}
+ ${pkgs.inetutils}/bin/ifconfig ${cfg.bridge} up
+ '';
+ serviceConfig.ExecStop = ''
+ ${pkgs.inetutils}/bin/ifconfig ${cfg.bridge} down
+ ${pkgs.bridge-utils}/bin/brctl delbr ${cfg.bridge}
+ '';
+ };
+
+ systemd.services.xen-domains = {
+ description = "Xen domains - automatically starts, saves and restores Xen domains";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "xen-bridge.service" "xen-qemu.service" ];
+ ## To prevent a race between dhcpcd and xend's bridge setup script
+ ## (which renames eth* to peth* and recreates eth* as a virtual
+ ## device), start dhcpcd after xend.
+ before = [ "dhcpd.service" ];
+ restartIfChanged = false;
+ serviceConfig.RemainAfterExit = "yes";
+ path = [ pkgs.xen ];
+ environment.XENDOM_CONFIG = "${pkgs.xen}/etc/sysconfig/xendomains";
+ preStart = "mkdir -p /var/lock/subsys -m 755";
+ serviceConfig.ExecStart = "${pkgs.xen}/etc/init.d/xendomains start";
+ serviceConfig.ExecStop = "${pkgs.xen}/etc/init.d/xendomains stop";
+ };
};
diff --git a/nixos/modules/virtualisation/xen-domU.nix b/nixos/modules/virtualisation/xen-domU.nix
index 48358966934..2db3190ad13 100644
--- a/nixos/modules/virtualisation/xen-domU.nix
+++ b/nixos/modules/virtualisation/xen-domU.nix
@@ -9,7 +9,10 @@
boot.loader.grub.device = "nodev";
boot.loader.grub.extraPerEntryConfig = "root (hd0)";
- boot.initrd.kernelModules = [ "xen-blkfront" ];
+ boot.initrd.kernelModules =
+ [ "xen-blkfront" "xen-tpmfront" "xen-kbdfront" "xen-fbfront"
+ "xen-netfront" "xen-pcifront" "xen-scsifront"
+ ];
# Send syslog messages to the Xen console.
services.syslogd.tty = "hvc0";
diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix
index 23348e1d089..cb1c200ab47 100644
--- a/nixos/release-combined.nix
+++ b/nixos/release-combined.nix
@@ -1,3 +1,7 @@
+# This jobset defines the main NixOS channels (such as nixos-unstable
+# and nixos-14.04). The channel is updated every time the ‘tested’ job
+# succeeds, and all other jobs have finished (they may fail).
+
{ nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; }
, stableBranch ? false
, supportedSystems ? [ "x86_64-linux" "i686-linux" ]
@@ -18,7 +22,7 @@ let
in rec {
nixos = removeMaintainers (import ./release.nix {
- inherit stableBranch;
+ inherit stableBranch supportedSystems;
nixpkgs = nixpkgsSrc;
});
@@ -27,40 +31,50 @@ in rec {
nixpkgs = nixpkgsSrc;
})) [ "unstable" ];
- tested = pkgs.releaseTools.aggregate {
+ tested = pkgs.lib.hydraJob (pkgs.releaseTools.aggregate {
name = "nixos-${nixos.channel.version}";
meta = {
- description = "Release-critical builds for the NixOS unstable channel";
- maintainers = [ pkgs.lib.maintainers.eelco pkgs.lib.maintainers.shlevy ];
+ description = "Release-critical builds for the NixOS channel";
+ maintainers = [ pkgs.lib.maintainers.eelco ];
};
constituents =
- let all = x: [ x.x86_64-linux x.i686-linux ]; in
+ let all = x: map (system: x.${system}) supportedSystems; in
[ nixos.channel
+ (all nixos.dummy)
(all nixos.manual)
(all nixos.iso_minimal)
(all nixos.iso_graphical)
(all nixos.ova)
- #(all nixos.tests.efi-installer.simple)
#(all nixos.tests.containers)
+ (all nixos.tests.chromium)
(all nixos.tests.firefox)
(all nixos.tests.firewall)
(all nixos.tests.gnome3)
- #(all nixos.tests.installer.efi)
- (all nixos.tests.installer.grub1)
(all nixos.tests.installer.lvm)
(all nixos.tests.installer.separateBoot)
(all nixos.tests.installer.simple)
(all nixos.tests.installer.simpleLabels)
(all nixos.tests.installer.simpleProvided)
+ (all nixos.tests.installer.swraid)
(all nixos.tests.installer.btrfsSimple)
(all nixos.tests.installer.btrfsSubvols)
+ (all nixos.tests.installer.btrfsSubvolDefault)
(all nixos.tests.ipv6)
(all nixos.tests.kde4)
(all nixos.tests.login)
(all nixos.tests.misc)
- (all nixos.tests.nat)
+ (all nixos.tests.nat.firewall)
+ (all nixos.tests.nat.standalone)
+ (all nixos.tests.networking.scripted.static)
+ (all nixos.tests.networking.scripted.dhcpSimple)
+ (all nixos.tests.networking.scripted.dhcpOneIf)
+ (all nixos.tests.networking.scripted.bond)
+ (all nixos.tests.networking.scripted.bridge)
+ (all nixos.tests.networking.scripted.macvlan)
+ (all nixos.tests.networking.scripted.sit)
+ (all nixos.tests.networking.scripted.vlan)
(all nixos.tests.nfs3)
(all nixos.tests.openssh)
(all nixos.tests.printing)
@@ -72,6 +86,6 @@ in rec {
nixpkgs.tarball
(all nixpkgs.emacs)
];
- };
+ });
}
diff --git a/nixos/release-small.nix b/nixos/release-small.nix
new file mode 100644
index 00000000000..11155c85369
--- /dev/null
+++ b/nixos/release-small.nix
@@ -0,0 +1,93 @@
+# This jobset is used to generate a NixOS channel that contains a
+# small subset of Nixpkgs, mostly useful for servers that need fast
+# security updates.
+
+{ nixpkgs ? { outPath = ./..; revCount = 56789; shortRev = "gfedcba"; }
+, stableBranch ? false
+, supportedSystems ? [ "x86_64-linux" ] # no i686-linux
+}:
+
+let
+
+ nixpkgsSrc = nixpkgs; # urgh
+
+ pkgs = import ./.. {};
+
+ lib = pkgs.lib;
+
+ nixos' = import ./release.nix {
+ inherit stableBranch supportedSystems;
+ nixpkgs = nixpkgsSrc;
+ };
+
+ nixpkgs' = builtins.removeAttrs (import ../pkgs/top-level/release.nix {
+ inherit supportedSystems;
+ nixpkgs = nixpkgsSrc;
+ }) [ "unstable" ];
+
+in rec {
+
+ nixos = {
+ inherit (nixos') channel manual iso_minimal dummy;
+ tests = {
+ inherit (nixos'.tests)
+ containers
+ firewall
+ ipv6
+ login
+ misc
+ nat
+ nfs3
+ openssh
+ proxy
+ simple;
+ installer = {
+ inherit (nixos'.tests.installer)
+ grub1
+ lvm
+ separateBoot
+ simple;
+ };
+ };
+ };
+
+ nixpkgs = {
+ inherit (nixpkgs')
+ apacheHttpd_2_2
+ apacheHttpd_2_4
+ cmake
+ cryptsetup
+ emacs
+ gettext
+ git
+ imagemagick
+ jdk
+ linux
+ mysql51
+ mysql55
+ nginx
+ nodejs
+ openssh
+ php
+ postgresql92
+ postgresql93
+ python
+ rsyslog
+ stdenv
+ subversion
+ tarball
+ vim;
+ };
+
+ tested = lib.hydraJob (pkgs.releaseTools.aggregate {
+ name = "nixos-${nixos.channel.version}";
+ meta = {
+ description = "Release-critical builds for the NixOS channel";
+ maintainers = [ lib.maintainers.eelco ];
+ };
+ constituents =
+ let all = x: map (system: x.${system}) supportedSystems; in
+ [ nixpkgs.tarball ] ++ lib.collect lib.isDerivation nixos;
+ });
+
+}
diff --git a/nixos/release.nix b/nixos/release.nix
index e5a4e7337ab..375b65d040e 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -3,20 +3,20 @@
, supportedSystems ? [ "x86_64-linux" "i686-linux" ]
}:
+with import ../lib;
+
let
version = builtins.readFile ../.version;
versionSuffix =
(if stableBranch then "." else "pre") + "${toString nixpkgs.revCount}.${nixpkgs.shortRev}";
- forAllSystems = pkgs.lib.genAttrs supportedSystems;
+ forAllSystems = genAttrs supportedSystems;
- callTest = fn: args: forAllSystems (system: import fn ({ inherit system; } // args));
+ callTest = fn: args: forAllSystems (system: hydraJob (import fn ({ inherit system; } // args)));
pkgs = import nixpkgs { system = "x86_64-linux"; };
- lib = pkgs.lib;
-
versionModule =
{ system.nixosVersionSuffix = versionSuffix;
@@ -40,10 +40,10 @@ let
in
# Declare the ISO as a build product so that it shows up in Hydra.
- runCommand "nixos-iso-${config.system.nixosVersion}"
+ hydraJob (runCommand "nixos-iso-${config.system.nixosVersion}"
{ meta = {
description = "NixOS installation CD (${description}) - ISO image for ${system}";
- maintainers = map (x: lib.getAttr x lib.maintainers) maintainers;
+ maintainers = map (x: lib.maintainers.${x}) maintainers;
};
inherit iso;
passthru = { inherit config; };
@@ -51,7 +51,7 @@ let
''
mkdir -p $out/nix-support
echo "file iso" $iso/iso/*.iso* >> $out/nix-support/hydra-build-products
- ''; # */
+ ''); # */
makeSystemTarball =
@@ -72,20 +72,23 @@ let
tarball //
{ meta = {
description = "NixOS system tarball for ${system} - ${stdenv.platform.name}";
- maintainers = map (x: lib.getAttr x lib.maintainers) maintainers;
+ maintainers = map (x: lib.maintainers.${x}) maintainers;
};
inherit config;
};
- makeClosure = module: forAllSystems (system: (import ./lib/eval-config.nix {
+ makeClosure = module: buildFromConfig module (config: config.system.build.toplevel);
+
+
+ buildFromConfig = module: sel: forAllSystems (system: hydraJob (sel (import ./lib/eval-config.nix {
inherit system;
- modules = [ module ] ++ lib.singleton
+ modules = [ module versionModule ] ++ singleton
({ config, lib, ... }:
- { fileSystems."/".device = lib.mkDefault "/dev/sda1";
- boot.loader.grub.device = lib.mkDefault "/dev/sda";
+ { fileSystems."/".device = mkDefault "/dev/sda1";
+ boot.loader.grub.device = mkDefault "/dev/sda";
});
- }).config.system.build.toplevel);
+ }).config));
in rec {
@@ -122,9 +125,14 @@ in rec {
};
- manual = forAllSystems (system: (builtins.getAttr system iso_minimal).config.system.build.manual.manual);
- manualPDF = iso_minimal.x86_64-linux.config.system.build.manual.manualPDF;
- manpages = forAllSystems (system: (builtins.getAttr system iso_minimal).config.system.build.manual.manpages);
+ manual = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manual);
+ manualPDF = (buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manualPDF)).x86_64-linux;
+ manpages = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.manpages);
+ options = (buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.manual.optionsJSON)).x86_64-linux;
+
+
+ # Build the initial ramdisk so Hydra can keep track of its size over time.
+ initialRamdisk = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.initialRamdisk);
iso_minimal = forAllSystems (system: makeIso {
@@ -147,12 +155,6 @@ in rec {
inherit system;
});
- iso_graphical_new_kernel = forAllSystems (system: makeIso {
- module = ./modules/installer/cd-dvd/installation-cd-graphical-new-kernel.nix;
- type = "graphical-new-kernel";
- inherit system;
- });
-
# A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF).
ova = forAllSystems (system:
@@ -171,10 +173,10 @@ in rec {
in
# Declare the OVA as a build product so that it shows up in Hydra.
- runCommand "nixos-ova-${config.system.nixosVersion}-${system}"
+ hydraJob (runCommand "nixos-ova-${config.system.nixosVersion}-${system}"
{ meta = {
description = "NixOS VirtualBox appliance (${system})";
- maintainers = lib.maintainers.eelco;
+ maintainers = maintainers.eelco;
};
ova = config.system.build.virtualBoxOVA;
}
@@ -182,11 +184,24 @@ in rec {
mkdir -p $out/nix-support
fn=$(echo $ova/*.ova)
echo "file ova $fn" >> $out/nix-support/hydra-build-products
- '' # */
+ '') # */
);
+ # Ensure that all packages used by the minimal NixOS config end up in the channel.
+ dummy = forAllSystems (system: pkgs.runCommand "dummy"
+ { toplevel = (import lib/eval-config.nix {
+ inherit system;
+ modules = singleton ({ config, pkgs, ... }:
+ { fileSystems."/".device = mkDefault "/dev/sda1";
+ boot.loader.grub.device = mkDefault "/dev/sda";
+ });
+ }).config.system.build.toplevel;
+ }
+ "mkdir $out; ln -s $toplevel $out/dummy");
+
+
# Provide a tarball that can be unpacked into an SD card, and easily
# boot that system from uboot (like for the sheevaplug).
# The pc variant helps preparing the expression for the system tarball
@@ -196,6 +211,12 @@ in rec {
inherit system;
});
+ # Provide container tarball for lxc, libvirt-lxc, docker-lxc, ...
+ containerTarball = forAllSystems (system: makeSystemTarball {
+ module = ./modules/virtualisation/lxc-container.nix;
+ inherit system;
+ });
+
/*
system_tarball_fuloong2f =
assert builtins.currentSystem == "mips64-linux";
@@ -218,30 +239,70 @@ in rec {
# ‘nix-build tests/login.nix -A result’.
tests.avahi = callTest tests/avahi.nix {};
tests.bittorrent = callTest tests/bittorrent.nix {};
+ tests.blivet = callTest tests/blivet.nix {};
+ tests.cadvisor = hydraJob (import tests/cadvisor.nix { system = "x86_64-linux"; });
+ tests.chromium = callTest tests/chromium.nix {};
+ tests.cjdns = callTest tests/cjdns.nix {};
tests.containers = callTest tests/containers.nix {};
+ tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; });
+ tests.dockerRegistry = hydraJob (import tests/docker-registry.nix { system = "x86_64-linux"; });
+ tests.etcd = hydraJob (import tests/etcd.nix { system = "x86_64-linux"; });
tests.firefox = callTest tests/firefox.nix {};
tests.firewall = callTest tests/firewall.nix {};
+ tests.fleet = hydraJob (import tests/fleet.nix { system = "x86_64-linux"; });
+ #tests.gitlab = callTest tests/gitlab.nix {};
tests.gnome3 = callTest tests/gnome3.nix {};
- tests.installer = with pkgs.lib;
- let installer = import tests/installer.nix; in
- flip mapAttrs (installer { }) (name: _:
- forAllSystems (system: (installer { system = system; }).${name}.test)
- );
+ tests.i3wm = callTest tests/i3wm.nix {};
+ tests.installer.grub1 = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).grub1.test);
+ tests.installer.lvm = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).lvm.test);
+ tests.installer.rebuildCD = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).rebuildCD.test);
+ tests.installer.separateBoot = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).separateBoot.test);
+ tests.installer.simple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simple.test);
+ tests.installer.simpleLabels = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleLabels.test);
+ tests.installer.simpleProvided = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).simpleProvided.test);
+ tests.installer.swraid = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).swraid.test);
+ tests.installer.btrfsSimple = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSimple.test);
+ tests.installer.btrfsSubvols = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvols.test);
+ tests.installer.btrfsSubvolDefault = forAllSystems (system: hydraJob (import tests/installer.nix { inherit system; }).btrfsSubvolDefault.test);
tests.influxdb = callTest tests/influxdb.nix {};
tests.ipv6 = callTest tests/ipv6.nix {};
tests.jenkins = callTest tests/jenkins.nix {};
tests.kde4 = callTest tests/kde4.nix {};
+ tests.kubernetes = hydraJob (import tests/kubernetes.nix { system = "x86_64-linux"; });
tests.latestKernel.login = callTest tests/login.nix { latestKernel = true; };
tests.login = callTest tests/login.nix {};
- tests.logstash = callTest tests/logstash.nix {};
+ #tests.logstash = callTest tests/logstash.nix {};
tests.misc = callTest tests/misc.nix {};
tests.mumble = callTest tests/mumble.nix {};
tests.munin = callTest tests/munin.nix {};
tests.mysql = callTest tests/mysql.nix {};
tests.mysqlReplication = callTest tests/mysql-replication.nix {};
- tests.nat = callTest tests/nat.nix {};
+ tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; };
+ tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; };
+ tests.networking.networkd.static = callTest tests/networking.nix { networkd = true; test = "static"; };
+ tests.networking.networkd.dhcpSimple = callTest tests/networking.nix { networkd = true; test = "dhcpSimple"; };
+ tests.networking.networkd.dhcpOneIf = callTest tests/networking.nix { networkd = true; test = "dhcpOneIf"; };
+ tests.networking.networkd.bond = callTest tests/networking.nix { networkd = true; test = "bond"; };
+ tests.networking.networkd.bridge = callTest tests/networking.nix { networkd = true; test = "bridge"; };
+ tests.networking.networkd.macvlan = callTest tests/networking.nix { networkd = true; test = "macvlan"; };
+ tests.networking.networkd.sit = callTest tests/networking.nix { networkd = true; test = "sit"; };
+ tests.networking.networkd.vlan = callTest tests/networking.nix { networkd = true; test = "vlan"; };
+ tests.networking.scripted.static = callTest tests/networking.nix { networkd = false; test = "static"; };
+ tests.networking.scripted.dhcpSimple = callTest tests/networking.nix { networkd = false; test = "dhcpSimple"; };
+ tests.networking.scripted.dhcpOneIf = callTest tests/networking.nix { networkd = false; test = "dhcpOneIf"; };
+ tests.networking.scripted.bond = callTest tests/networking.nix { networkd = false; test = "bond"; };
+ tests.networking.scripted.bridge = callTest tests/networking.nix { networkd = false; test = "bridge"; };
+ tests.networking.scripted.macvlan = callTest tests/networking.nix { networkd = false; test = "macvlan"; };
+ tests.networking.scripted.sit = callTest tests/networking.nix { networkd = false; test = "sit"; };
+ tests.networking.scripted.vlan = callTest tests/networking.nix { networkd = false; test = "vlan"; };
+ # TODO: put in networking.nix after the test becomes more complete
+ tests.networkingProxy = callTest tests/networking-proxy.nix {};
tests.nfs3 = callTest tests/nfs.nix { version = 3; };
+ tests.nfs4 = callTest tests/nfs.nix { version = 4; };
+ tests.nsd = callTest tests/nsd.nix {};
tests.openssh = callTest tests/openssh.nix {};
+ tests.panamax = hydraJob (import tests/panamax.nix { system = "x86_64-linux"; });
+ tests.peerflix = callTest tests/peerflix.nix {};
tests.printing = callTest tests/printing.nix {};
tests.proxy = callTest tests/proxy.nix {};
tests.quake3 = callTest tests/quake3.nix {};
@@ -249,7 +310,12 @@ in rec {
tests.simple = callTest tests/simple.nix {};
tests.tomcat = callTest tests/tomcat.nix {};
tests.udisks2 = callTest tests/udisks2.nix {};
+ tests.virtualbox = hydraJob (import tests/virtualbox.nix { system = "x86_64-linux"; });
tests.xfce = callTest tests/xfce.nix {};
+ tests.bootBiosCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosCdrom);
+ tests.bootBiosUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootBiosUsb);
+ tests.bootUefiCdrom = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiCdrom);
+ tests.bootUefiUsb = forAllSystems (system: hydraJob (import tests/boot.nix { inherit system; }).bootUefiUsb);
/* Build a bunch of typical closures so that Hydra can keep track of
diff --git a/nixos/tests/bittorrent.nix b/nixos/tests/bittorrent.nix
index 002e012f65f..0d0f00212a0 100644
--- a/nixos/tests/bittorrent.nix
+++ b/nixos/tests/bittorrent.nix
@@ -16,7 +16,7 @@ let
miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf"
''
ext_ifname=eth1
- listening_ip=${nodes.router.config.networking.interfaces.eth2.ipAddress}/24
+ listening_ip=${(pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address}/24
allow 1024-65535 192.168.2.0/24 1024-65535
'';
@@ -28,7 +28,7 @@ in
nodes =
{ tracker =
{ config, pkgs, ... }:
- { environment.systemPackages = [ pkgs.transmission pkgs.bittorrent ];
+ { environment.systemPackages = [ pkgs.transmission pkgs.opentracker ];
# We need Apache on the tracker to serve the torrents.
services.httpd.enable = true;
@@ -53,7 +53,7 @@ in
{ environment.systemPackages = [ pkgs.transmission ];
virtualisation.vlans = [ 2 ];
networking.defaultGateway =
- nodes.router.config.networking.interfaces.eth2.ipAddress;
+ (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address;
networking.firewall.enable = false;
};
@@ -81,12 +81,12 @@ in
# Create the torrent.
$tracker->succeed("mkdir /tmp/data");
$tracker->succeed("cp ${file} /tmp/data/test.tar.bz2");
- $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -t http://${nodes.tracker.config.networking.interfaces.eth1.ipAddress}:6969/announce -o /tmp/test.torrent");
+ $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -p -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ip4).address}:6969/announce -o /tmp/test.torrent");
$tracker->succeed("chmod 644 /tmp/test.torrent");
# Start the tracker. !!! use a less crappy tracker
$tracker->waitForUnit("network.target");
- $tracker->succeed("bittorrent-tracker --port 6969 --dfile /tmp/dstate >&2 &");
+ $tracker->succeed("opentracker -p 6969 >&2 &");
$tracker->waitForOpenPort(6969);
# Start the initial seeder.
diff --git a/nixos/tests/blivet.nix b/nixos/tests/blivet.nix
new file mode 100644
index 00000000000..72c2a33f87e
--- /dev/null
+++ b/nixos/tests/blivet.nix
@@ -0,0 +1,83 @@
+import ./make-test.nix ({ pkgs, ... }: with pkgs.pythonPackages; rec {
+ name = "blivet";
+
+ machine = {
+ environment.systemPackages = [ pkgs.python blivet mock ];
+ boot.supportedFilesystems = [ "btrfs" "jfs" "reiserfs" "xfs" ];
+ virtualisation.memorySize = 768;
+ };
+
+ debugBlivet = false;
+ debugProgramCalls = false;
+
+ pythonTestRunner = pkgs.writeText "run-blivet-tests.py" ''
+ import sys
+ import logging
+
+ from unittest import TestLoader
+ from unittest.runner import TextTestRunner
+
+ ${pkgs.lib.optionalString debugProgramCalls ''
+ blivet_program_log = logging.getLogger("program")
+ blivet_program_log.setLevel(logging.DEBUG)
+ blivet_program_log.addHandler(logging.StreamHandler(sys.stderr))
+ ''}
+
+ ${pkgs.lib.optionalString debugBlivet ''
+ blivet_log = logging.getLogger("blivet")
+ blivet_log.setLevel(logging.DEBUG)
+ blivet_log.addHandler(logging.StreamHandler(sys.stderr))
+ ''}
+
+ runner = TextTestRunner(verbosity=2, failfast=False, buffer=False)
+ result = runner.run(TestLoader().discover('tests/', pattern='*_test.py'))
+ sys.exit(not result.wasSuccessful())
+ '';
+
+ blivetTest = pkgs.writeScript "blivet-test.sh" ''
+ #!${pkgs.stdenv.shell} -e
+
+ # Use the hosts temporary directory, because we have a tmpfs within the VM
+ # and we don't want to increase the memory size of the VM for no reason.
+ mkdir -p /tmp/xchg/bigtmp
+ TMPDIR=/tmp/xchg/bigtmp
+ export TMPDIR
+
+ cp -Rd "${blivet.src}/tests" .
+
+ # Skip SELinux tests
+ rm -f tests/formats_test/selinux_test.py
+
+ # Race conditions in growing/shrinking during resync
+ rm -f tests/devicelibs_test/mdraid_*
+
+ # Deactivate small BTRFS device test, because it fails with newer btrfsprogs
+ sed -i -e '/^class *BTRFSAsRootTestCase3(/,/^[^ ]/ {
+ /^class *BTRFSAsRootTestCase3(/d
+ /^$/d
+ /^ /d
+ }' tests/devicelibs_test/btrfs_test.py
+
+ # How on earth can these tests ever work even upstream? O_o
+ sed -i -e '/def testDiskChunk[12]/,/^ *[^ ]/{n; s/^ */&return # /}' \
+ tests/partitioning_test.py
+
+ # fix hardcoded temporary directory
+ sed -i \
+ -e '1i import tempfile' \
+ -e 's|_STORE_FILE_PATH = .*|_STORE_FILE_PATH = tempfile.gettempdir()|' \
+ tests/loopbackedtestcase.py
+
+ PYTHONPATH=".:$(< "${pkgs.stdenv.mkDerivation {
+ name = "blivet-pythonpath";
+ buildInputs = [ blivet mock ];
+ buildCommand = "echo \"$PYTHONPATH\" > \"$out\"";
+ }}")" python "${pythonTestRunner}"
+ '';
+
+ testScript = ''
+ $machine->waitForUnit("multi-user.target");
+ $machine->succeed("${blivetTest}");
+ $machine->execute("rm -rf /tmp/xchg/bigtmp");
+ '';
+})
diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix
new file mode 100644
index 00000000000..2fdbb0c00b8
--- /dev/null
+++ b/nixos/tests/boot.nix
@@ -0,0 +1,63 @@
+{ system ? builtins.currentSystem }:
+
+with import ../lib/testing.nix { inherit system; };
+with import ../lib/qemu-flags.nix;
+with pkgs.lib;
+
+let
+
+ iso =
+ (import ../lib/eval-config.nix {
+ inherit system;
+ modules =
+ [ ../modules/installer/cd-dvd/installation-cd-minimal.nix
+ ../modules/testing/test-instrumentation.nix
+ { key = "serial";
+ boot.loader.grub.timeout = mkOverride 0 0;
+
+ # The test cannot access the network, so any sources we
+ # need must be included in the ISO.
+ isoImage.storeContents =
+ [ pkgs.glibcLocales
+ pkgs.sudo
+ pkgs.docbook5
+ pkgs.docbook5_xsl
+ pkgs.grub
+ pkgs.perlPackages.XMLLibXML
+ pkgs.unionfs-fuse
+ pkgs.gummiboot
+ ];
+ }
+ ];
+ }).config.system.build.isoImage;
+
+ makeBootTest = name: machineConfig:
+ makeTest {
+ inherit iso;
+ name = "boot-" + name;
+ nodes = { };
+ testScript =
+ ''
+ my $machine = createMachine({ ${machineConfig}, qemuFlags => '-m 768' });
+ $machine->start;
+ $machine->waitForUnit("multi-user.target");
+ $machine->shutdown;
+ '';
+ };
+in {
+ bootBiosCdrom = makeBootTest "bios-cdrom" ''
+ cdrom => glob("${iso}/iso/*.iso")
+ '';
+ bootBiosUsb = makeBootTest "bios-usb" ''
+ usb => glob("${iso}/iso/*.iso")
+ '';
+ bootUefiCdrom = makeBootTest "uefi-cdrom" ''
+ cdrom => glob("${iso}/iso/*.iso"),
+ bios => '${pkgs.OVMF}/FV/OVMF.fd'
+ '';
+ bootUefiUsb = makeBootTest "uefi-usb" ''
+ usb => glob("${iso}/iso/*.iso"),
+ bios => '${pkgs.OVMF}/FV/OVMF.fd'
+ '';
+ }
+
diff --git a/nixos/tests/cadvisor.nix b/nixos/tests/cadvisor.nix
new file mode 100644
index 00000000000..225bf1a7483
--- /dev/null
+++ b/nixos/tests/cadvisor.nix
@@ -0,0 +1,30 @@
+import ./make-test.nix {
+ name = "cadvisor";
+
+ nodes = {
+ machine = { config, pkgs, ... }: {
+ services.cadvisor.enable = true;
+ };
+
+ influxdb = { config, pkgs, lib, ... }: with lib; {
+ services.cadvisor.enable = true;
+ services.cadvisor.storageDriver = "influxdb";
+ services.influxdb.enable = true;
+ systemd.services.influxdb.postStart = mkAfter ''
+ ${pkgs.curl}/bin/curl -X POST 'http://localhost:8086/db?u=root&p=root' \
+ -d '{"name": "root"}'
+ '';
+ };
+ };
+
+ testScript =
+ ''
+ startAll;
+ $machine->waitForUnit("cadvisor.service");
+ $machine->succeed("curl http://localhost:8080/containers/");
+
+ $influxdb->waitForUnit("influxdb.service");
+ $influxdb->waitForUnit("cadvisor.service");
+ $influxdb->succeed("curl http://localhost:8080/containers/");
+ '';
+}
diff --git a/nixos/tests/chromium.nix b/nixos/tests/chromium.nix
new file mode 100644
index 00000000000..026433fc7ee
--- /dev/null
+++ b/nixos/tests/chromium.nix
@@ -0,0 +1,170 @@
+import ./make-test.nix (
+{ pkgs
+, channelMap ? {
+ stable = pkgs.chromium;
+ beta = pkgs.chromiumBeta;
+ dev = pkgs.chromiumDev;
+ }
+, ...
+}: rec {
+ name = "chromium";
+
+ machine.imports = [ ./common/x11.nix ];
+ machine.virtualisation.memorySize = 1024;
+
+ startupHTML = pkgs.writeText "chromium-startup.html" ''
+
+
+
+
+ Chromium startup notifier
+
+
+
+
+
+ '';
+
+ testScript = let
+ xdo = name: text: let
+ xdoScript = pkgs.writeText "${name}.xdo" text;
+ in "${pkgs.xdotool}/bin/xdotool '${xdoScript}'";
+ in ''
+ sub createNewWin {
+ $machine->nest("creating a new Chromium window", sub {
+ $machine->execute("${xdo "new-window" ''
+ search --onlyvisible --name "startup done"
+ windowfocus --sync
+ windowactivate --sync
+ key Ctrl+n
+ ''}");
+ });
+ }
+
+ sub closeWin {
+ Machine::retry sub {
+ $machine->execute("${xdo "close-window" ''
+ search --onlyvisible --name "new tab"
+ windowfocus --sync
+ windowactivate --sync
+ key Ctrl+w
+ ''}");
+ for (1..20) {
+ my ($status, $out) = $machine->execute("${xdo "wait-for-close" ''
+ search --onlyvisible --name "new tab"
+ ''}");
+ return 1 if $status != 0;
+ $machine->sleep(1);
+ }
+ }
+ }
+
+ sub waitForNewWin {
+ my $ret = 0;
+ $machine->nest("waiting for new Chromium window to appear", sub {
+ for (1..20) {
+ my ($status, $out) = $machine->execute("${xdo "wait-for-window" ''
+ search --onlyvisible --name "new tab"
+ windowfocus --sync
+ windowactivate --sync
+ ''}");
+ if ($status == 0) {
+ $ret = 1;
+ last;
+ }
+ $machine->sleep(1);
+ }
+ });
+ return $ret;
+ }
+
+ sub createAndWaitForNewWin {
+ for (1..3) {
+ createNewWin;
+ return 1 if waitForNewWin;
+ }
+ die "new window didn't appear within 60 seconds";
+ }
+
+ sub testNewWin {
+ my ($desc, $code) = @_;
+ createAndWaitForNewWin;
+ subtest($desc, $code);
+ closeWin;
+ }
+
+ sub chromiumTest {
+ my ($channel, $pkg, $code) = @_;
+ $machine->waitForX;
+
+ my $url = "file://${startupHTML}";
+ my $args = "--user-data-dir=/tmp/chromium-$channel";
+ $machine->execute(
+ "ulimit -c unlimited; ".
+ "$pkg/bin/chromium $args \"$url\" & disown"
+ );
+ $machine->waitUntilSucceeds("${xdo "check-startup" ''
+ search --sync --onlyvisible --name "startup done"
+ # close first start help popup
+ key -delay 1000 Escape
+ # XXX: This is to make sure the popup is closed, but we better do
+ # screenshots to detect visual changes.
+ key -delay 2000 Escape
+ key -delay 3000 Escape
+ key -delay 4000 Escape
+ windowfocus --sync
+ windowactivate --sync
+ ''}");
+
+ createAndWaitForNewWin;
+ $machine->screenshot($channel."_emptywin");
+ closeWin;
+
+ $machine->screenshot($channel."_startup_done");
+
+ subtest("Chromium $channel", $code);
+
+ $machine->shutdown;
+ }
+
+ for (${let
+ mkArray = name: pkg: "[\"${name}\", \"${pkg}\"]";
+ chanArrays = pkgs.lib.mapAttrsToList mkArray channelMap;
+ in pkgs.lib.concatStringsSep ", " chanArrays}) {
+ my ($channel, $pkg) = @$_;
+ chromiumTest $channel, $pkg, sub {
+ testNewWin "check sandbox", sub {
+ $machine->succeed("${xdo "type-url" ''
+ search --sync --onlyvisible --name "new tab"
+ windowfocus --sync
+ type --delay 1000 "chrome://sandbox"
+ ''}");
+
+ $machine->succeed("${xdo "submit-url" ''
+ search --sync --onlyvisible --name "new tab"
+ windowfocus --sync
+ key --delay 1000 Return
+ ''}");
+
+ $machine->screenshot($channel."_sandbox");
+
+ $machine->succeed("${xdo "submit-url" ''
+ search --sync --onlyvisible --name "sandbox status"
+ windowfocus --sync
+ key --delay 1000 Ctrl+a Ctrl+c
+ ''}");
+
+ my $clipboard = $machine->succeed("${pkgs.xclip}/bin/xclip -o");
+ die "sandbox not working properly: $clipboard"
+ unless $clipboard =~ /(?:suid|namespace) sandbox.*yes/mi
+ && $clipboard =~ /pid namespaces.*yes/mi
+ && $clipboard =~ /network namespaces.*yes/mi
+ && $clipboard =~ /seccomp.*sandbox.*yes/mi;
+ };
+ };
+ }
+ '';
+})
diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix
new file mode 100644
index 00000000000..45164234b1b
--- /dev/null
+++ b/nixos/tests/cjdns.nix
@@ -0,0 +1,122 @@
+let
+ carolKey = "2d2a338b46f8e4a8c462f0c385b481292a05f678e19a2b82755258cf0f0af7e2";
+ carolPubKey = "n932l3pjvmhtxxcdrqq2qpw5zc58f01vvjx01h4dtd1bb0nnu2h0.k";
+ carolPassword = "678287829ce4c67bc8b227e56d94422ee1b85fa11618157b2f591de6c6322b52";
+ carolIp4 = "192.168.0.9";
+
+ basicConfig =
+ { config, pkgs, ... }:
+ { services.cjdns.enable = true;
+
+ # Turning off DHCP isn't very realistic but makes
+ # the sequence of address assignment less stochastic.
+ networking.useDHCP = false;
+
+ networking.interfaces.eth1.prefixLength = 24;
+ # CJDNS output is incompatible with the XML log.
+ systemd.services.cjdns.serviceConfig.StandardOutput = "null";
+ #networking.firewall.enable = true;
+ networking.firewall.allowPing = true;
+ #networking.firewall.rejectPackets = true;
+ };
+
+in
+
+import ./make-test.nix {
+ name = "cjdns";
+
+ nodes = rec
+ { # Alice finds peers over over ETHInterface.
+ alice =
+ { config, ... }:
+ { imports = [ basicConfig ];
+
+ services.cjdns.ETHInterface.bind = "eth1";
+
+ services.httpd.enable = true;
+ services.httpd.adminAddr = "foo@example.org";
+ networking.firewall.allowedTCPPorts = [ 80 ];
+ };
+
+ # Bob explicitly connects to Carol over UDPInterface.
+ bob =
+ { config, lib, nodes, ... }:
+
+ let carolIp4 = lib.mkForce nodes.carol.config.networking.interfaces.eth1; in
+
+ { imports = [ basicConfig ];
+
+ networking.interfaces.eth1.ipAddress = "192.168.0.2";
+
+ services.cjdns =
+ { UDPInterface =
+ { bind = "0.0.0.0:1024";
+ connectTo."192.168.0.1:1024}" =
+ { password = carolPassword;
+ publicKey = carolPubKey;
+ };
+ };
+ };
+ };
+
+ # Carol listens on ETHInterface and UDPInterface,
+ # but knows neither Alice or Bob.
+ carol =
+ { config, lib, nodes, ... }:
+ let
+ carolIp4 = (lib.mkForce nodes.carol.config.networking.interfaces.eth1);
+ in
+ { imports = [ basicConfig ];
+
+ environment.etc."cjdns.keys".text = ''
+ CJDNS_PRIVATE_KEY=${carolKey}
+ CJDNS_ADMIN_PASSWORD=FOOBAR
+ '';
+
+ networking.interfaces.eth1.ipAddress = "192.168.0.1";
+
+ services.cjdns =
+ { authorizedPasswords = [ carolPassword ];
+ ETHInterface.bind = "eth1";
+ UDPInterface.bind = "192.168.0.1:1024";
+ };
+ networking.firewall.allowedUDPPorts = [ 1024 ];
+ };
+
+ };
+
+ testScript =
+ ''
+ startAll;
+
+ $alice->waitForUnit("cjdns.service");
+ $bob->waitForUnit("cjdns.service");
+ $carol->waitForUnit("cjdns.service");
+
+ sub cjdnsIp {
+ my ($machine) = @_;
+ my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev tun0"))[3];
+ $machine->log("has ip $ip");
+ return $ip;
+ }
+
+ my $aliceIp6 = cjdnsIp $alice;
+ my $bobIp6 = cjdnsIp $bob;
+ my $carolIp6 = cjdnsIp $carol;
+
+ # ping a few times each to let the routing table establish itself
+
+ $alice->succeed("ping6 -c 4 $carolIp6");
+ $bob->succeed("ping6 -c 4 $carolIp6");
+
+ $carol->succeed("ping6 -c 4 $aliceIp6");
+ $carol->succeed("ping6 -c 4 $bobIp6");
+
+ $alice->succeed("ping6 -c 4 $bobIp6");
+ $bob->succeed("ping6 -c 4 $aliceIp6");
+
+ $alice->waitForUnit("httpd.service");
+
+ $bob->succeed("curl --fail -g http://[$aliceIp6]");
+ '';
+}
diff --git a/nixos/tests/containers.nix b/nixos/tests/containers.nix
index a582e23fda0..e40a8100a06 100644
--- a/nixos/tests/containers.nix
+++ b/nixos/tests/containers.nix
@@ -43,7 +43,7 @@ import ./make-test.nix {
$machine->fail("curl --fail --connect-timeout 2 http://$ip/ > /dev/null");
# Make sure we have a NixOS tree (required by ‘nixos-container create’).
- $machine->succeed("nix-env -qa -A nixos.pkgs.hello >&2");
+ $machine->succeed("PAGER=cat nix-env -qa -A nixos.pkgs.hello >&2");
# Create some containers imperatively.
my $id1 = $machine->succeed("nixos-container create foo --ensure-unique-name");
@@ -56,23 +56,59 @@ import ./make-test.nix {
die if $id1 eq $id2;
+ # Put the root of $id2 into a bind mount.
+ $machine->succeed(
+ "mv /var/lib/containers/$id2 /id2-bindmount",
+ "mount --bind /id2-bindmount /var/lib/containers/$id1"
+ );
+
my $ip1 = $machine->succeed("nixos-container show-ip $id1");
chomp $ip1;
my $ip2 = $machine->succeed("nixos-container show-ip $id2");
chomp $ip2;
die if $ip1 eq $ip2;
+ # Create a directory and a file we can later check if it still exists
+ # after destruction of the container.
+ $machine->succeed(
+ "mkdir /nested-bindmount",
+ "echo important data > /nested-bindmount/dummy",
+ );
+
+ # Create a directory with a dummy file and bind-mount it into both
+ # containers.
+ foreach ($id1, $id2) {
+ my $importantPath = "/var/lib/containers/$_/very/important/data";
+ $machine->succeed(
+ "mkdir -p $importantPath",
+ "mount --bind /nested-bindmount $importantPath"
+ );
+ }
+
# Start one of them.
$machine->succeed("nixos-container start $id1");
# Execute commands via the root shell.
$machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
- $machine->succeed("nixos-container set-root-password $id1 foobar");
+
+ # Stop and start (regression test for #4989)
+ $machine->succeed("nixos-container stop $id1");
+ $machine->succeed("nixos-container start $id1");
+
+ # Execute commands via the root shell.
+ $machine->succeed("nixos-container run $id1 -- uname") =~ /Linux/ or die;
# Destroy the containers.
$machine->succeed("nixos-container destroy $id1");
$machine->succeed("nixos-container destroy $id2");
+ $machine->succeed(
+ # Check whether destruction of any container has killed important data
+ "grep -qF 'important data' /nested-bindmount/dummy",
+ # Ensure that the container path is gone
+ "test ! -e /var/lib/containers/$id1"
+ );
+
# Destroying a declarative container should fail.
$machine->fail("nixos-container destroy webserver");
'';
diff --git a/nixos/tests/docker-registry.nix b/nixos/tests/docker-registry.nix
new file mode 100644
index 00000000000..cc3c4774680
--- /dev/null
+++ b/nixos/tests/docker-registry.nix
@@ -0,0 +1,40 @@
+# This test runs docker-registry and check if it works
+
+import ./make-test.nix {
+ name = "docker-registry";
+
+ nodes = {
+ registry = { config, pkgs, ... }: {
+ services.dockerRegistry.enable = true;
+ services.dockerRegistry.port = 8080;
+ services.dockerRegistry.host = "0.0.0.0";
+ networking.firewall.allowedTCPPorts = [ 8080 ];
+ };
+
+ client1 = { config, pkgs, ...}: {
+ virtualisation.docker.enable = true;
+ virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
+ };
+
+ client2 = { config, pkgs, ...}: {
+ virtualisation.docker.enable = true;
+ virtualisation.docker.extraOptions = "--insecure-registry registry:8080";
+ };
+ };
+
+ testScript = ''
+ $client1->start();
+ $client1->waitForUnit("docker.service");
+ $client1->succeed("tar cv --files-from /dev/null | docker import - scratch");
+ $client1->succeed("docker tag scratch registry:8080/scratch");
+
+ $registry->start();
+ $registry->waitForUnit("docker-registry.service");
+ $client1->succeed("docker push registry:8080/scratch");
+
+ $client2->start();
+ $client2->waitForUnit("docker.service");
+ $client2->succeed("docker pull registry:8080/scratch");
+ $client2->succeed("docker images | grep scratch");
+ '';
+}
diff --git a/nixos/tests/docker.nix b/nixos/tests/docker.nix
new file mode 100644
index 00000000000..63c909ff294
--- /dev/null
+++ b/nixos/tests/docker.nix
@@ -0,0 +1,24 @@
+# This test runs docker and checks if simple container starts
+
+import ./make-test.nix {
+ name = "docker";
+
+ nodes = {
+ docker =
+ { config, pkgs, ... }:
+ {
+ virtualisation.docker.enable = true;
+ };
+ };
+
+ testScript = ''
+ startAll;
+
+ $docker->waitForUnit("docker.service");
+ $docker->succeed("tar cv --files-from /dev/null | docker import - scratch");
+ $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratch /bin/sleep 10");
+ $docker->succeed("docker ps | grep sleeping");
+ $docker->succeed("docker stop sleeping");
+ '';
+
+}
diff --git a/nixos/tests/etcd.nix b/nixos/tests/etcd.nix
new file mode 100644
index 00000000000..ace5e05b170
--- /dev/null
+++ b/nixos/tests/etcd.nix
@@ -0,0 +1,108 @@
+# This test runs etcd as single node, multy node and using discovery
+
+import ./make-test.nix {
+ name = "etcd";
+
+ nodes = {
+ simple =
+ { config, pkgs, nodes, ... }:
+ {
+ services.etcd.enable = true;
+ services.etcd.listenClientUrls = ["http://0.0.0.0:4001"];
+ environment.systemPackages = [ pkgs.curl ];
+ networking.firewall.allowedTCPPorts = [ 4001 ];
+ };
+
+
+ node1 =
+ { config, pkgs, nodes, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://node1:7001"];
+ initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"];
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+
+ node2 =
+ { config, pkgs, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://node2:7001"];
+ initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"];
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+
+ discovery1 =
+ { config, pkgs, nodes, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://discovery1:7001"];
+ discovery = "http://simple:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/";
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+
+ discovery2 =
+ { config, pkgs, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://discovery2:7001"];
+ discovery = "http://simple:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/";
+ };
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+ };
+
+ testScript = ''
+ subtest "single node", sub {
+ $simple->start();
+ $simple->waitForUnit("etcd.service");
+ $simple->succeed("etcdctl set /foo/bar 'Hello world'");
+ $simple->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'");
+ };
+
+ subtest "multy node", sub {
+ $node1->start();
+ $node2->start();
+ $node1->waitForUnit("etcd.service");
+ $node2->waitForUnit("etcd.service");
+ $node1->succeed("etcdctl set /foo/bar 'Hello world'");
+ $node2->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'");
+ $node1->shutdown();
+ $node2->shutdown();
+ };
+
+ subtest "discovery", sub {
+ $simple->succeed("curl -X PUT http://localhost:4001/v2/keys/discovery/6c007a14875d53d9bf0ef5a6fc0257c817f0fb83/_config/size -d value=2");
+
+ $discovery1->start();
+ $discovery2->start();
+ $discovery1->waitForUnit("etcd.service");
+ $discovery2->waitForUnit("etcd.service");
+ $discovery1->succeed("etcdctl set /foo/bar 'Hello world'");
+ $discovery2->waitUntilSucceeds("etcdctl get /foo/bar | grep 'Hello world'");
+ };
+ '';
+}
diff --git a/nixos/tests/fleet.nix b/nixos/tests/fleet.nix
new file mode 100644
index 00000000000..c60f596b6f5
--- /dev/null
+++ b/nixos/tests/fleet.nix
@@ -0,0 +1,73 @@
+import ./make-test.nix rec {
+ name = "simple";
+
+ nodes = {
+ node1 =
+ { config, pkgs, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://node1:7001"];
+ initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"];
+ };
+ };
+
+ services.fleet = {
+ enable = true;
+ metadata.name = "node1";
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+
+ node2 =
+ { config, pkgs, ... }:
+ {
+ services = {
+ etcd = {
+ enable = true;
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://node2:7001"];
+ initialCluster = ["node1=http://node1:7001" "node2=http://node2:7001"];
+ };
+ };
+
+ services.fleet = {
+ enable = true;
+ metadata.name = "node2";
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7001 ];
+ };
+ };
+
+ service = builtins.toFile "hello.service" ''
+ [Unit]
+ Description=Hello World
+
+ [Service]
+ ExecStart=/bin/sh -c "while true; do echo \"Hello, world\"; /var/run/current-system/sw/bin/sleep 1; done"
+
+ [X-Fleet]
+ MachineMetadata=name=node2
+ '';
+
+ testScript =
+ ''
+ startAll;
+ $node1->waitForUnit("fleet.service");
+ $node2->waitForUnit("fleet.service");
+
+ $node2->waitUntilSucceeds("fleetctl list-machines | grep node1");
+ $node1->waitUntilSucceeds("fleetctl list-machines | grep node2");
+
+ $node1->succeed("cp ${service} hello.service && fleetctl submit hello.service");
+ $node1->succeed("fleetctl list-unit-files | grep hello");
+ $node1->succeed("fleetctl start hello.service");
+ $node1->waitUntilSucceeds("fleetctl list-units | grep running");
+ $node1->succeed("fleetctl stop hello.service");
+ $node1->succeed("fleetctl destroy hello.service");
+ '';
+}
diff --git a/nixos/tests/gitlab.nix b/nixos/tests/gitlab.nix
new file mode 100644
index 00000000000..27c65fe47e8
--- /dev/null
+++ b/nixos/tests/gitlab.nix
@@ -0,0 +1,21 @@
+# This test runs gitlab and checks if it works
+
+import ./make-test.nix {
+ name = "gitlab";
+
+ nodes = {
+ gitlab = { config, pkgs, ... }: {
+ virtualisation.memorySize = 768;
+ services.gitlab.enable = true;
+ services.gitlab.databasePassword = "gitlab";
+ systemd.services.gitlab.serviceConfig.TimeoutStartSec = "10min";
+ };
+ };
+
+ testScript = ''
+ $gitlab->start();
+ $gitlab->waitForUnit("gitlab.service");
+ $gitlab->waitForUnit("gitlab-sidekiq.service");
+ $gitlab->waitUntilSucceeds("curl http://localhost:8080/users/sign_in");
+ '';
+}
diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix
index 44668f57fc1..6f2925e52fa 100644
--- a/nixos/tests/gnome3.nix
+++ b/nixos/tests/gnome3.nix
@@ -11,6 +11,8 @@ import ./make-test.nix {
services.xserver.displayManager.auto.enable = true;
services.xserver.displayManager.auto.user = "alice";
services.xserver.desktopManager.gnome3.enable = true;
+
+ virtualisation.memorySize = 512;
};
testScript =
@@ -23,7 +25,7 @@ import ./make-test.nix {
$machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
$machine->waitForWindow(qr/Terminal/);
- $machine->sleep(10);
+ $machine->sleep(20);
$machine->screenshot("screen");
'';
diff --git a/nixos/tests/gnome3_12.nix b/nixos/tests/gnome3_12.nix
deleted file mode 100644
index 439674b69d5..00000000000
--- a/nixos/tests/gnome3_12.nix
+++ /dev/null
@@ -1,31 +0,0 @@
-import ./make-test.nix {
- name = "gnome3_12";
-
- machine =
- { config, pkgs, ... }:
-
- { imports = [ ./common/user-account.nix ];
-
- services.xserver.enable = true;
-
- services.xserver.displayManager.auto.enable = true;
- services.xserver.displayManager.auto.user = "alice";
- services.xserver.desktopManager.gnome3.enable = true;
- environment.gnome3.packageSet = pkgs.gnome3_12;
- };
-
- testScript =
- ''
- $machine->waitForX;
- $machine->sleep(15);
-
- # Check that logging in has given the user ownership of devices.
- $machine->succeed("getfacl /dev/snd/timer | grep -q alice");
-
- $machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
- $machine->waitForWindow(qr/Terminal/);
- $machine->sleep(10);
- $machine->screenshot("screen");
- '';
-
-}
diff --git a/nixos/tests/i3wm.nix b/nixos/tests/i3wm.nix
new file mode 100644
index 00000000000..0966dba8a3c
--- /dev/null
+++ b/nixos/tests/i3wm.nix
@@ -0,0 +1,28 @@
+import ./make-test.nix {
+ name = "i3wm";
+
+ machine = { lib, pkgs, ... }: {
+ imports = [ ./common/x11.nix ./common/user-account.nix ];
+ services.xserver.displayManager.auto.user = "alice";
+ services.xserver.windowManager.default = lib.mkForce "i3";
+ services.xserver.windowManager.i3.enable = true;
+ };
+
+ testScript = { nodes, ... }: ''
+ $machine->waitForX;
+ $machine->waitForWindow(qr/first configuration/);
+ $machine->sleep(1);
+ $machine->screenshot("started");
+ $machine->sendKeys("ret");
+ $machine->sleep(1);
+ $machine->sendKeys("alt");
+ $machine->sleep(1);
+ $machine->screenshot("configured");
+ $machine->sendKeys("ret");
+ $machine->sleep(2);
+ $machine->sendKeys("alt-ret");
+ $machine->waitForWindow(qr/machine.*alice/);
+ $machine->sleep(1);
+ $machine->screenshot("terminal");
+ '';
+}
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index ef11fcb1001..af87705b927 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -6,13 +6,13 @@ with pkgs.lib;
let
- # Build the ISO. This is the regular installation CD but with test
- # instrumentation.
+ # Build the ISO. This is the regular minimal installation CD but
+ # with test instrumentation.
iso =
(import ../lib/eval-config.nix {
inherit system;
modules =
- [ ../modules/installer/cd-dvd/installation-cd-graphical.nix
+ [ ../modules/installer/cd-dvd/installation-cd-minimal.nix
../modules/testing/test-instrumentation.nix
{ key = "serial";
boot.loader.grub.timeout = mkOverride 0 0;
@@ -24,40 +24,52 @@ let
pkgs.sudo
pkgs.docbook5
pkgs.docbook5_xsl
- pkgs.grub
- pkgs.perlPackages.XMLLibXML
pkgs.unionfs-fuse
+
+ # Bootloader support
+ pkgs.grub
+ pkgs.grub2
+ pkgs.grub2_efi
pkgs.gummiboot
+ pkgs.perlPackages.XMLLibXML
+ pkgs.perlPackages.ListCompare
];
+
+ # Don't use https://cache.nixos.org since the fake
+ # cache.nixos.org doesn't do https.
+ nix.binaryCaches = [ http://cache.nixos.org/ ];
}
];
}).config.system.build.isoImage;
# The configuration to install.
- makeConfig = { testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
+ makeConfig = { testChannel, grubVersion, grubDevice, grubIdentifier
+ , readOnly ? true, forceGrubReinstallCount ? 0 }:
pkgs.writeText "configuration.nix" ''
- { config, pkgs, modulesPath, ... }:
+ { config, lib, pkgs, modulesPath, ... }:
{ imports =
[ ./hardware-configuration.nix
+
];
- ${if useEFI then ''
- boot.loader.efi.canTouchEfiVariables = true;
- boot.loader.gummiboot.enable = true;
- '' else ''
- boot.loader.grub.version = ${toString grubVersion};
- ${optionalString (grubVersion == 1) ''
- boot.loader.grub.splashImage = null;
- ''}
- boot.loader.grub.device = "${grubDevice}";
- boot.loader.grub.extraConfig = "serial; terminal_output.serial";
- boot.loader.grub.fsIdentifier = "${grubIdentifier}";
+ boot.loader.grub.version = ${toString grubVersion};
+ ${optionalString (grubVersion == 1) ''
+ boot.loader.grub.splashImage = null;
''}
+ boot.loader.grub.device = "${grubDevice}";
+ boot.loader.grub.extraConfig = "serial; terminal_output.serial";
+ boot.loader.grub.fsIdentifier = "${grubIdentifier}";
+
+ boot.loader.grub.configurationLimit = 100 + ${toString forceGrubReinstallCount};
+
+ ${optionalString (!readOnly) "nix.readOnlyStore = false;"}
environment.systemPackages = [ ${optionalString testChannel "pkgs.rlwrap"} ];
+
+ nix.binaryCaches = [ http://cache.nixos.org/ ];
}
'';
@@ -65,7 +77,7 @@ let
# Configuration of a web server that simulates the Nixpkgs channel
# distribution server.
webserver =
- { config, pkgs, ... }:
+ { config, lib, pkgs, ... }:
{ services.httpd.enable = true;
services.httpd.adminAddr = "foo@example.org";
@@ -94,16 +106,14 @@ let
# disk, and then reboot from the hard disk. It's parameterized with
# a test script fragment `createPartitions', which must create
# partitions and filesystems.
- testScriptFun = { createPartitions, testChannel, useEFI, grubVersion, grubDevice, grubIdentifier }:
+ testScriptFun = { createPartitions, testChannel, grubVersion, grubDevice, grubIdentifier }:
let
# FIXME: OVMF doesn't boot from virtio http://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg01501.html
- iface = if useEFI || grubVersion == 1 then "scsi" else "virtio";
+ iface = if grubVersion == 1 then "scsi" else "virtio";
qemuFlags =
(if iso.system == "x86_64-linux" then "-m 768 " else "-m 512 ") +
- (optionalString (iso.system == "x86_64-linux") "-cpu kvm64 ") +
- (optionalString useEFI ''-L ${efiBios} -hda ''${\(Cwd::abs_path('harddisk'))} '');
- hdFlags = optionalString (!useEFI)
- ''hda => "harddisk", hdaInterface => "${iface}", '';
+ (optionalString (iso.system == "x86_64-linux") "-cpu kvm64 ");
+ hdFlags =''hda => "harddisk", hdaInterface => "${iface}", '';
in
''
createDisk("harddisk", 4 * 1024);
@@ -162,7 +172,7 @@ let
$machine->succeed("cat /mnt/etc/nixos/hardware-configuration.nix >&2");
$machine->copyFileFromHost(
- "${ makeConfig { inherit testChannel useEFI grubVersion grubDevice grubIdentifier; } }",
+ "${ makeConfig { inherit testChannel grubVersion grubDevice grubIdentifier; } }",
"/mnt/etc/nixos/configuration.nix");
# Perform the installation.
@@ -183,31 +193,45 @@ let
# Did /boot get mounted?
$machine->waitForUnit("local-fs.target");
- ${if useEFI then ''
- $machine->succeed("test -e /boot/efi");
- '' else ''
- $machine->succeed("test -e /boot/grub");
- ''}
+ $machine->succeed("test -e /boot/grub");
+
+ # Check whether /root has correct permissions.
+ $machine->succeed("stat -c '%a' /root") =~ /700/ or die;
# Did the swap device get activated?
- $machine->waitForUnit("swap.target");
- $machine->succeed("cat /proc/swaps | grep -q /dev");
+ # uncomment once https://bugs.freedesktop.org/show_bug.cgi?id=86930 is resolved
+ #$machine->waitForUnit("swap.target");
+ $machine->waitUntilSucceeds("cat /proc/swaps | grep -q /dev");
# Check whether the channel works.
$machine->succeed("nix-env -i coreutils >&2");
$machine->succeed("type -tP ls | tee /dev/stderr") =~ /.nix-profile/
or die "nix-env failed";
+ # We need to a writable nix-store on next boot
+ $machine->copyFileFromHost(
+ "${ makeConfig { inherit testChannel grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 1; } }",
+ "/etc/nixos/configuration.nix");
+
# Check whether nixos-rebuild works.
$machine->succeed("nixos-rebuild switch >&2");
# Test nixos-option.
$machine->succeed("nixos-option boot.initrd.kernelModules | grep virtio_console");
- $machine->succeed("nixos-option -d boot.initrd.kernelModules | grep 'List of modules'");
- $machine->succeed("nixos-option -l boot.initrd.kernelModules | grep qemu-guest.nix");
+ $machine->succeed("nixos-option boot.initrd.kernelModules | grep 'List of modules'");
+ $machine->succeed("nixos-option boot.initrd.kernelModules | grep qemu-guest.nix");
$machine->shutdown;
+ # Check whether a writable store build works
+ $machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
+ $machine->waitForUnit("multi-user.target");
+ $machine->copyFileFromHost(
+ "${ makeConfig { inherit testChannel grubVersion grubDevice grubIdentifier; readOnly = false; forceGrubReinstallCount = 2; } }",
+ "/etc/nixos/configuration.nix");
+ $machine->succeed("nixos-rebuild boot >&2");
+ $machine->shutdown;
+
# And just to be sure, check that the machine still boots after
# "nixos-rebuild switch".
$machine = createMachine({ ${hdFlags} qemuFlags => "${qemuFlags}" });
@@ -217,13 +241,13 @@ let
makeInstallerTest = name:
- { createPartitions, testChannel ? false, useEFI ? false, grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid" }:
+ { createPartitions, testChannel ? false, grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid" }:
makeTest {
inherit iso;
name = "installer-" + name;
nodes = if testChannel then { inherit webserver; } else { };
testScript = testScriptFun {
- inherit createPartitions testChannel useEFI grubVersion grubDevice grubIdentifier;
+ inherit createPartitions testChannel grubVersion grubDevice grubIdentifier;
};
};
@@ -303,12 +327,12 @@ in {
$machine->succeed(
"parted /dev/vda --"
. " mklabel msdos"
- . " mkpart primary ext2 1M 30MB" # /boot
- . " mkpart extended 30M -1s"
- . " mkpart logical 31M 1531M" # md0 (root), first device
- . " mkpart logical 1540M 3040M" # md0 (root), second device
- . " mkpart logical 3050M 3306M" # md1 (swap), first device
- . " mkpart logical 3320M 3576M", # md1 (swap), second device
+ . " mkpart primary ext2 1M 100MB" # /boot
+ . " mkpart extended 100M -1s"
+ . " mkpart logical 102M 1602M" # md0 (root), first device
+ . " mkpart logical 1603M 3103M" # md0 (root), second device
+ . " mkpart logical 3104M 3360M" # md1 (swap), first device
+ . " mkpart logical 3361M 3617M", # md1 (swap), second device
"udevadm settle",
"ls -l /dev/vda* >&2",
"cat /proc/partitions >&2",
@@ -349,25 +373,6 @@ in {
grubDevice = "/dev/sda";
};
- # Test an EFI install.
- efi = makeInstallerTest "efi"
- { createPartitions =
- ''
- $machine->succeed(
- "sgdisk -Z /dev/sda",
- "sgdisk -n 1:0:+256M -n 2:0:+1024M -N 3 -t 1:ef00 -t 2:8200 -t 3:8300 -c 1:boot -c 2:swap -c 3:root /dev/sda",
- "mkfs.vfat -n BOOT /dev/sda1",
- "mkswap /dev/sda2 -L swap",
- "swapon -L swap",
- "mkfs.ext3 -L nixos /dev/sda3",
- "mount LABEL=nixos /mnt",
- "mkdir /mnt/boot",
- "mount LABEL=BOOT /mnt/boot",
- );
- '';
- useEFI = true;
- };
-
# Rebuild the CD configuration with a little modification.
rebuildCD = makeTest
{ inherit iso;
@@ -397,7 +402,7 @@ in {
};
# Test using labels to identify volumes in grub
- simpleLabels = makeInstallerTest {
+ simpleLabels = makeInstallerTest "simpleLabels" {
createPartitions = ''
$machine->succeed(
"sgdisk -Z /dev/vda",
@@ -413,7 +418,7 @@ in {
# Test using the provided disk name within grub
# TODO: Fix udev so the symlinks are unneeded in /dev/disks
- simpleProvided = makeInstallerTest {
+ simpleProvided = makeInstallerTest "simpleProvided" {
createPartitions = ''
my $UUID = "\$(blkid -s UUID -o value /dev/vda2)";
$machine->succeed(
@@ -436,7 +441,7 @@ in {
};
# Simple btrfs grub testing
- btrfsSimple = makeInstallerTest {
+ btrfsSimple = makeInstallerTest "btrfsSimple" {
createPartitions = ''
$machine->succeed(
"sgdisk -Z /dev/vda",
@@ -450,7 +455,7 @@ in {
};
# Test to see if we can detect /boot and /nix on subvolumes
- btrfsSubvols = makeInstallerTest {
+ btrfsSubvols = makeInstallerTest "btrfsSubvols" {
createPartitions = ''
$machine->succeed(
"sgdisk -Z /dev/vda",
@@ -462,11 +467,36 @@ in {
"mount LABEL=root /mnt",
"btrfs subvol create /mnt/boot",
"btrfs subvol create /mnt/nixos",
+ "btrfs subvol create /mnt/nixos/default",
"umount /mnt",
- "mount -o defaults,subvol=nixos LABEL=root /mnt",
+ "mount -o defaults,subvol=nixos/default LABEL=root /mnt",
"mkdir /mnt/boot",
"mount -o defaults,subvol=boot LABEL=root /mnt/boot",
);
'';
};
+
+ # Test to see if we can detect default and aux subvolumes correctly
+ btrfsSubvolDefault = makeInstallerTest "btrfsSubvolDefault" {
+ createPartitions = ''
+ $machine->succeed(
+ "sgdisk -Z /dev/vda",
+ "sgdisk -n 1:0:+1M -n 2:0:+1G -N 3 -t 1:ef02 -t 2:8200 -t 3:8300 -c 3:root /dev/vda",
+ "mkswap /dev/vda2 -L swap",
+ "swapon -L swap",
+ "mkfs.btrfs -L root /dev/vda3",
+ "btrfs device scan",
+ "mount LABEL=root /mnt",
+ "btrfs subvol create /mnt/badpath",
+ "btrfs subvol create /mnt/badpath/boot",
+ "btrfs subvol create /mnt/nixos",
+ "btrfs subvol set-default \$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt",
+ "umount /mnt",
+ "mount -o defaults LABEL=root /mnt",
+ "mkdir -p /mnt/badpath/boot", # Help ensure the detection mechanism is actually looking up subvolumes
+ "mkdir /mnt/boot",
+ "mount -o defaults,subvol=badpath/boot LABEL=root /mnt/boot",
+ );
+ '';
+ };
}
diff --git a/nixos/tests/jenkins.nix b/nixos/tests/jenkins.nix
index 28027c294bc..d737038380d 100644
--- a/nixos/tests/jenkins.nix
+++ b/nixos/tests/jenkins.nix
@@ -16,6 +16,8 @@ import ./make-test.nix {
services.jenkinsSlave.enable = true;
users.extraUsers.jenkins.extraGroups = [ "users" ];
+
+ systemd.services.jenkins.serviceConfig.TimeoutStartSec = "6min";
};
slave =
diff --git a/nixos/tests/kde4.nix b/nixos/tests/kde4.nix
index 90c37397821..dd2574fd02a 100644
--- a/nixos/tests/kde4.nix
+++ b/nixos/tests/kde4.nix
@@ -32,7 +32,7 @@ import ./make-test.nix ({ pkgs, ... }: {
pkgs.kde4.kdegraphics
pkgs.kde4.kdeutils
pkgs.kde4.kdegames
- pkgs.kde4.kdeedu
+ #pkgs.kde4.kdeedu
pkgs.kde4.kdeaccessibility
pkgs.kde4.kdeadmin
pkgs.kde4.kdenetwork
@@ -41,8 +41,7 @@ import ./make-test.nix ({ pkgs, ... }: {
];
};
- testScript =
- ''
+ testScript = ''
$machine->waitUntilSucceeds("pgrep plasma-desktop");
$machine->waitForWindow(qr/plasma-desktop/);
@@ -60,7 +59,7 @@ import ./make-test.nix ({ pkgs, ... }: {
$machine->sleep(10);
- $machine->screenshot("screen");
+ $machine->screenshot("screen");
'';
})
diff --git a/nixos/tests/kubernetes.nix b/nixos/tests/kubernetes.nix
new file mode 100644
index 00000000000..0a9eda930ba
--- /dev/null
+++ b/nixos/tests/kubernetes.nix
@@ -0,0 +1,179 @@
+# This test runs two node kubernetes cluster and checks if simple redis pod works
+
+import ./make-test.nix rec {
+ name = "kubernetes";
+
+ redisMaster = builtins.toFile "redis-master-pod.yaml" ''
+ id: redis-master-pod
+ kind: Pod
+ apiVersion: v1beta1
+ desiredState:
+ manifest:
+ version: v1beta1
+ id: redis-master-pod
+ containers:
+ - name: master
+ image: master:5000/nix
+ cpu: 100
+ ports:
+ - name: redis-server
+ containerPort: 6379
+ hostPort: 6379
+ volumeMounts:
+ - name: nix-store
+ mountPath: /nix/store
+ readOnly: true
+ volumeMounts:
+ - name: system-profile
+ mountPath: /bin
+ readOnly: true
+ command:
+ - /bin/redis-server
+ volumes:
+ - name: nix-store
+ source:
+ hostDir:
+ path: /nix/store
+ - name: system-profile
+ source:
+ hostDir:
+ path: /run/current-system/sw/bin
+ labels:
+ name: redis
+ role: master
+ '';
+
+ nodes = {
+ master =
+ { config, pkgs, lib, nodes, ... }:
+ {
+ virtualisation.memorySize = 768;
+ services.kubernetes = {
+ roles = ["master" "node"];
+ dockerCfg = ''{"master:5000":{}}'';
+ controllerManager.machines = ["master" "node"];
+ apiserver.address = "0.0.0.0";
+ verbose = true;
+ };
+ virtualisation.docker.extraOptions = "--iptables=false --ip-masq=false -b cbr0 --insecure-registry master:5000";
+
+ services.etcd = {
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://master:7001"];
+ initialCluster = ["master=http://master:7001" "node=http://node:7001"];
+ };
+ services.dockerRegistry.enable = true;
+ services.dockerRegistry.host = "0.0.0.0";
+ services.dockerRegistry.port = 5000;
+
+ virtualisation.vlans = [ 1 2 ];
+ networking.bridges = {
+ cbr0.interfaces = [ "eth2" ];
+ };
+ networking.interfaces = {
+ cbr0 = {
+ ipAddress = "10.10.0.1";
+ prefixLength = 24;
+ };
+ eth2.ip4 = lib.mkOverride 0 [ ];
+ };
+ networking.localCommands = ''
+ ip route add 10.10.0.0/16 dev cbr0
+ ip route flush cache
+ '';
+ networking.extraHosts = "127.0.0.1 master";
+
+ networking.firewall.enable = false;
+ #networking.firewall.allowedTCPPorts = [ 4001 7001 ];
+
+ environment.systemPackages = [ pkgs.redis ];
+ };
+
+ node =
+ { config, pkgs, lib, nodes, ... }:
+ {
+ services.kubernetes = {
+ roles = ["node"];
+ dockerCfg = ''{"master:5000":{}}'';
+ kubelet.apiServers = ["master:8080"];
+ verbose = true;
+ };
+ virtualisation.docker.extraOptions = "--iptables=false --ip-masq=false -b cbr0 --insecure-registry master:5000";
+ services.etcd = {
+ listenPeerUrls = ["http://0.0.0.0:7001"];
+ initialAdvertisePeerUrls = ["http://node:7001"];
+ initialCluster = ["master=http://master:7001" "node=http://node:7001"];
+ };
+
+ virtualisation.vlans = [ 1 2 ];
+ networking.bridges = {
+ cbr0.interfaces = [ "eth2" ];
+ };
+ networking.interfaces = {
+ cbr0 = {
+ ipAddress = "10.10.1.1";
+ prefixLength = 24;
+ };
+ eth2.ip4 = lib.mkOverride 0 [ ];
+ };
+ networking.localCommands = ''
+ ip route add 10.10.0.0/16 dev cbr0
+ ip route flush cache
+ '';
+ networking.extraHosts = "127.0.0.1 node";
+
+ networking.firewall.enable = false;
+ #networking.firewall.allowedTCPPorts = [ 4001 7001 ];
+
+ environment.systemPackages = [ pkgs.redis ];
+ };
+
+ client =
+ { config, pkgs, nodes, ... }:
+ {
+ virtualisation.docker.enable = true;
+ virtualisation.docker.extraOptions = "--insecure-registry master:5000";
+ environment.systemPackages = [ pkgs.kubernetes ];
+ environment.etc."test/redis-master-pod.yaml".source = redisMaster;
+ environment.etc."test/pause".source = "${pkgs.kubernetes}/bin/kube-pause";
+ environment.etc."test/Dockerfile".source = pkgs.writeText "Dockerfile" ''
+ FROM scratch
+ ADD pause /
+ ENTRYPOINT ["/pause"]
+ '';
+ };
+ };
+
+ testScript = ''
+ startAll;
+
+ $master->waitForUnit("kubernetes-apiserver.service");
+ $master->waitForUnit("kubernetes-scheduler.service");
+ $master->waitForUnit("kubernetes-controller-manager.service");
+ $master->waitForUnit("kubernetes-kubelet.service");
+ $master->waitForUnit("kubernetes-proxy.service");
+
+ $node->waitForUnit("kubernetes-kubelet.service");
+ $node->waitForUnit("kubernetes-proxy.service");
+
+ $master->waitUntilSucceeds("kubectl get minions | grep master");
+ $master->waitUntilSucceeds("kubectl get minions | grep node");
+
+ $client->waitForUnit("docker.service");
+ $client->succeed("tar cv --files-from /dev/null | docker import - nix");
+ $client->succeed("docker tag nix master:5000/nix");
+ $master->waitForUnit("docker-registry.service");
+ $client->succeed("docker push master:5000/nix");
+ $client->succeed("mkdir -p /root/pause");
+ $client->succeed("cp /etc/test/pause /root/pause/");
+ $client->succeed("cp /etc/test/Dockerfile /root/pause/");
+ $client->succeed("cd /root/pause && docker build -t master:5000/pause .");
+ $client->succeed("docker push master:5000/pause");
+
+ subtest "simple pod", sub {
+ $client->succeed("kubectl create -f ${redisMaster} -s http://master:8080");
+ $client->waitUntilSucceeds("kubectl get pods -s http://master:8080 | grep redis-master | grep -i running");
+ }
+
+ '';
+}
diff --git a/nixos/tests/mesos.nix b/nixos/tests/mesos.nix
new file mode 100644
index 00000000000..040f613c596
--- /dev/null
+++ b/nixos/tests/mesos.nix
@@ -0,0 +1,29 @@
+import ./make-test.nix {
+ name = "simple";
+
+ machine = { config, pkgs, ... }: {
+ services.zookeeper.enable = true;
+ virtualisation.docker.enable = true;
+ services.mesos = {
+ slave = {
+ enable = true;
+ master = "zk://localhost:2181/mesos";
+ attributes = {
+ tag1 = "foo";
+ tag2 = "bar";
+ };
+ };
+ master = {
+ enable = true;
+ zk = "zk://localhost:2181/mesos";
+ };
+ };
+ };
+
+ testScript =
+ ''
+ startAll;
+ $machine->waitForUnit("mesos-master.service");
+ $machine->waitForUnit("mesos-slave.service");
+ '';
+}
diff --git a/nixos/tests/misc.nix b/nixos/tests/misc.nix
index e1830d95b41..b44af5316be 100644
--- a/nixos/tests/misc.nix
+++ b/nixos/tests/misc.nix
@@ -102,6 +102,10 @@ import ./make-test.nix {
subtest "shell-vars", sub {
$machine->succeed('[ -n "$NIX_PATH" ]');
};
+
+ subtest "nix-db", sub {
+ $machine->succeed("nix-store -qR /run/current-system | grep nixos-");
+ };
'';
}
diff --git a/nixos/tests/munin.nix b/nixos/tests/munin.nix
index 31676c10df1..1e51453df83 100644
--- a/nixos/tests/munin.nix
+++ b/nixos/tests/munin.nix
@@ -18,6 +18,7 @@ import ./make-test.nix {
'';
};
};
+ systemd.services.munin-node.serviceConfig.TimeoutStartSec = "3min";
};
};
diff --git a/nixos/tests/nat.nix b/nixos/tests/nat.nix
index 5fdcc0e97ca..c4d2614f785 100644
--- a/nixos/tests/nat.nix
+++ b/nixos/tests/nat.nix
@@ -3,77 +3,81 @@
# client on the inside network, a server on the outside network, and a
# router connected to both that performs Network Address Translation
# for the client.
+import ./make-test.nix ({ withFirewall, ... }:
+ let
+ unit = if withFirewall then "firewall" else "nat";
+ in
+ {
+ name = "nat${if withFirewall then "WithFirewall" else "Standalone"}";
-import ./make-test.nix {
- name = "nat";
+ nodes =
+ { client =
+ { config, pkgs, nodes, ... }:
+ { virtualisation.vlans = [ 1 ];
+ networking.firewall.allowPing = true;
+ networking.defaultGateway =
+ (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address;
+ };
- nodes =
- { client =
- { config, pkgs, nodes, ... }:
- { virtualisation.vlans = [ 1 ];
- networking.firewall.allowPing = true;
- networking.defaultGateway =
- nodes.router.config.networking.interfaces.eth2.ipAddress;
- };
+ router =
+ { config, pkgs, ... }:
+ { virtualisation.vlans = [ 2 1 ];
+ networking.firewall.enable = withFirewall;
+ networking.firewall.allowPing = true;
+ networking.nat.enable = true;
+ networking.nat.internalIPs = [ "192.168.1.0/24" ];
+ networking.nat.externalInterface = "eth1";
+ };
- router =
- { config, pkgs, ... }:
- { virtualisation.vlans = [ 2 1 ];
- networking.firewall.allowPing = true;
- networking.nat.enable = true;
- networking.nat.internalIPs = [ "192.168.1.0/24" ];
- networking.nat.externalInterface = "eth1";
- };
+ server =
+ { config, pkgs, ... }:
+ { virtualisation.vlans = [ 2 ];
+ networking.firewall.enable = false;
+ services.httpd.enable = true;
+ services.httpd.adminAddr = "foo@example.org";
+ services.vsftpd.enable = true;
+ services.vsftpd.anonymousUser = true;
+ };
+ };
- server =
- { config, pkgs, ... }:
- { virtualisation.vlans = [ 2 ];
- networking.firewall.enable = false;
- services.httpd.enable = true;
- services.httpd.adminAddr = "foo@example.org";
- services.vsftpd.enable = true;
- services.vsftpd.anonymousUser = true;
- };
- };
+ testScript =
+ { nodes, ... }:
+ ''
+ startAll;
- testScript =
- { nodes, ... }:
- ''
- startAll;
+ # The router should have access to the server.
+ $server->waitForUnit("network.target");
+ $server->waitForUnit("httpd");
+ $router->waitForUnit("network.target");
+ $router->succeed("curl --fail http://server/ >&2");
- # The router should have access to the server.
- $server->waitForUnit("network.target");
- $server->waitForUnit("httpd");
- $router->waitForUnit("network.target");
- $router->succeed("curl --fail http://server/ >&2");
+ # The client should be also able to connect via the NAT router.
+ $router->waitForUnit("${unit}");
+ $client->waitForUnit("network.target");
+ $client->succeed("curl --fail http://server/ >&2");
+ $client->succeed("ping -c 1 server >&2");
- # The client should be also able to connect via the NAT router.
- $router->waitForUnit("nat");
- $client->waitForUnit("network.target");
- $client->succeed("curl --fail http://server/ >&2");
- $client->succeed("ping -c 1 server >&2");
+ # Test whether passive FTP works.
+ $server->waitForUnit("vsftpd");
+ $server->succeed("echo Hello World > /home/ftp/foo.txt");
+ $client->succeed("curl -v ftp://server/foo.txt >&2");
- # Test whether passive FTP works.
- $server->waitForUnit("vsftpd");
- $server->succeed("echo Hello World > /home/ftp/foo.txt");
- $client->succeed("curl -v ftp://server/foo.txt >&2");
+ # Test whether active FTP works.
+ $client->succeed("curl -v -P - ftp://server/foo.txt >&2");
- # Test whether active FTP works.
- $client->succeed("curl -v -P - ftp://server/foo.txt >&2");
+ # Test ICMP.
+ $client->succeed("ping -c 1 router >&2");
+ $router->succeed("ping -c 1 client >&2");
- # Test ICMP.
- $client->succeed("ping -c 1 router >&2");
- $router->succeed("ping -c 1 client >&2");
+ # If we turn off NAT, the client shouldn't be able to reach the server.
+ $router->succeed("iptables -t nat -D PREROUTING -j nixos-nat-pre");
+ $router->succeed("iptables -t nat -D POSTROUTING -j nixos-nat-post");
+ $client->fail("curl --fail --connect-timeout 5 http://server/ >&2");
+ $client->fail("ping -c 1 server >&2");
- # If we turn off NAT, the client shouldn't be able to reach the server.
- $router->stopJob("nat");
- $client->fail("curl --fail --connect-timeout 5 http://server/ >&2");
- $client->fail("ping -c 1 server >&2");
-
- # And make sure that restarting the NAT job works.
- $router->succeed("systemctl start nat");
- $client->succeed("curl --fail http://server/ >&2");
- $client->succeed("ping -c 1 server >&2");
- '';
-
-}
+ # And make sure that reloading the NAT job works.
+ $router->succeed("systemctl restart ${unit}");
+ $client->succeed("curl --fail http://server/ >&2");
+ $client->succeed("ping -c 1 server >&2");
+ '';
+ })
diff --git a/nixos/tests/networking-proxy.nix b/nixos/tests/networking-proxy.nix
new file mode 100644
index 00000000000..30844805ebf
--- /dev/null
+++ b/nixos/tests/networking-proxy.nix
@@ -0,0 +1,109 @@
+# Test whether `networking.proxy' work as expected.
+
+# TODO: use a real proxy node and put this test into networking.nix
+# TODO: test whether nix tools work as expected behind a proxy
+
+let default-config = {
+ imports = [ ./common/user-account.nix ];
+
+ services.xserver.enable = false;
+
+ virtualisation.memorySize = 128;
+ };
+in import ./make-test.nix {
+ name = "networking-proxy";
+
+ nodes = {
+ # no proxy
+ machine =
+ { config, pkgs, ... }:
+
+ default-config;
+
+ # proxy default
+ machine2 =
+ { config, pkgs, ... }:
+
+ default-config // {
+ networking.proxy.default = "http://user:pass@host:port";
+ };
+
+ # specific proxy options
+ machine3 =
+ { config, pkgs, ... }:
+
+ default-config //
+ {
+ networking.proxy = {
+ # useless because overriden by the next options
+ default = "http://user:pass@host:port";
+ # advanced proxy setup
+ httpProxy = "123-http://user:pass@http-host:port";
+ httpsProxy = "456-http://user:pass@https-host:port";
+ rsyncProxy = "789-http://user:pass@rsync-host:port";
+ ftpProxy = "101112-http://user:pass@ftp-host:port";
+ noProxy = "131415-127.0.0.1,localhost,.localdomain";
+ };
+ };
+
+ # mix default + proxy options
+ machine4 =
+ { config, pkgs, ... }:
+
+ default-config // {
+ networking.proxy = {
+ # open for all *_proxy env var
+ default = "000-http://user:pass@default-host:port";
+ # except for those 2
+ rsyncProxy = "123-http://user:pass@http-host:port";
+ noProxy = "131415-127.0.0.1,localhost,.localdomain";
+ };
+ };
+ };
+
+ testScript =
+ ''
+ startAll;
+
+ # no proxy at all
+ print $machine->execute("env | grep -i proxy");
+ print $machine->execute("su - alice -c 'env | grep -i proxy'");
+ $machine->mustFail("env | grep -i proxy");
+ $machine->mustFail("su - alice -c 'env | grep -i proxy'");
+
+ # Use a default proxy option
+ print $machine2->execute("env | grep -i proxy");
+ print $machine2->execute("su - alice -c 'env | grep -i proxy'");
+ $machine2->mustSucceed("env | grep -i proxy");
+ $machine2->mustSucceed("su - alice -c 'env | grep -i proxy'");
+
+ # explicitly set each proxy option
+ print $machine3->execute("env | grep -i proxy");
+ print $machine3->execute("su - alice -c 'env | grep -i proxy'");
+ $machine3->mustSucceed("env | grep -i http_proxy | grep 123");
+ $machine3->mustSucceed("env | grep -i https_proxy | grep 456");
+ $machine3->mustSucceed("env | grep -i rsync_proxy | grep 789");
+ $machine3->mustSucceed("env | grep -i ftp_proxy | grep 101112");
+ $machine3->mustSucceed("env | grep -i no_proxy | grep 131415");
+ $machine3->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 123'");
+ $machine3->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 456'");
+ $machine3->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 789'");
+ $machine3->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 101112'");
+ $machine3->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'");
+
+ # set default proxy option + some other specifics
+ print $machine4->execute("env | grep -i proxy");
+ print $machine4->execute("su - alice -c 'env | grep -i proxy'");
+ $machine4->mustSucceed("env | grep -i http_proxy | grep 000");
+ $machine4->mustSucceed("env | grep -i https_proxy | grep 000");
+ $machine4->mustSucceed("env | grep -i rsync_proxy | grep 123");
+ $machine4->mustSucceed("env | grep -i ftp_proxy | grep 000");
+ $machine4->mustSucceed("env | grep -i no_proxy | grep 131415");
+ $machine4->mustSucceed("su - alice -c 'env | grep -i http_proxy | grep 000'");
+ $machine4->mustSucceed("su - alice -c 'env | grep -i https_proxy | grep 000'");
+ $machine4->mustSucceed("su - alice -c 'env | grep -i rsync_proxy | grep 123'");
+ $machine4->mustSucceed("su - alice -c 'env | grep -i ftp_proxy | grep 000'");
+ $machine4->mustSucceed("su - alice -c 'env | grep -i no_proxy | grep 131415'");
+ '';
+
+}
diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix
new file mode 100644
index 00000000000..46d0422f9c6
--- /dev/null
+++ b/nixos/tests/networking.nix
@@ -0,0 +1,381 @@
+import ./make-test.nix ({ networkd, test, ... }:
+ let
+ router = { config, pkgs, ... }:
+ with pkgs.lib;
+ let
+ vlanIfs = range 1 (length config.virtualisation.vlans);
+ in {
+ virtualisation.vlans = [ 1 2 3 ];
+ networking = {
+ useDHCP = false;
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
+ nameValuePair "eth${toString n}" {
+ ipAddress = "192.168.${toString n}.1";
+ prefixLength = 24;
+ })));
+ };
+ services.dhcpd = {
+ enable = true;
+ interfaces = map (n: "eth${toString n}") vlanIfs;
+ extraConfig = ''
+ option subnet-mask 255.255.255.0;
+ '' + flip concatMapStrings vlanIfs (n: ''
+ subnet 192.168.${toString n}.0 netmask 255.255.255.0 {
+ option broadcast-address 192.168.${toString n}.255;
+ option routers 192.168.${toString n}.1;
+ range 192.168.${toString n}.2 192.168.${toString n}.254;
+ }
+ '');
+ };
+ };
+ testCases = {
+ static = {
+ name = "Static";
+ nodes.router = router;
+ nodes.client = { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 2 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ defaultGateway = "192.168.1.1";
+ interfaces.eth1.ip4 = mkOverride 0 [
+ { address = "192.168.1.2"; prefixLength = 24; }
+ { address = "192.168.1.3"; prefixLength = 32; }
+ { address = "192.168.1.10"; prefixLength = 32; }
+ ];
+ interfaces.eth2.ip4 = mkOverride 0 [
+ { address = "192.168.2.2"; prefixLength = 24; }
+ ];
+ };
+ };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client->waitForUnit("network-interfaces.target");
+ $client->waitForUnit("network.target");
+ $router->waitForUnit("network-interfaces.target");
+ $router->waitForUnit("network.target");
+
+ # Make sure dhcpcd is not started
+ $client->fail("systemctl status dhcpcd.service");
+
+ # Test vlan 1
+ $client->succeed("ping -c 1 192.168.1.1");
+ $client->succeed("ping -c 1 192.168.1.2");
+ $client->succeed("ping -c 1 192.168.1.3");
+ $client->succeed("ping -c 1 192.168.1.10");
+
+ $router->succeed("ping -c 1 192.168.1.1");
+ $router->succeed("ping -c 1 192.168.1.2");
+ $router->succeed("ping -c 1 192.168.1.3");
+ $router->succeed("ping -c 1 192.168.1.10");
+
+ # Test vlan 2
+ $client->succeed("ping -c 1 192.168.2.1");
+ $client->succeed("ping -c 1 192.168.2.2");
+
+ $router->succeed("ping -c 1 192.168.2.1");
+ $router->succeed("ping -c 1 192.168.2.2");
+
+ # Test default gateway
+ $router->succeed("ping -c 1 192.168.3.1");
+ $client->succeed("ping -c 1 192.168.3.1");
+ '';
+ };
+ dhcpSimple = {
+ name = "SimpleDHCP";
+ nodes.router = router;
+ nodes.client = { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 2 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = true;
+ interfaces.eth1.ip4 = mkOverride 0 [ ];
+ interfaces.eth2.ip4 = mkOverride 0 [ ];
+ };
+ };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client->waitForUnit("network-interfaces.target");
+ $client->waitForUnit("network.target");
+ $router->waitForUnit("network-interfaces.target");
+ $router->waitForUnit("network.target");
+
+ # Wait until we have an ip address on each interface
+ $client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
+ $client->succeed("while ! ip addr show dev eth2 | grep '192.168.2'; do true; done");
+
+ # Test vlan 1
+ $client->succeed("ping -c 1 192.168.1.1");
+ $client->succeed("ping -c 1 192.168.1.2");
+
+ $router->succeed("ping -c 1 192.168.1.1");
+ $router->succeed("ping -c 1 192.168.1.2");
+
+ # Test vlan 2
+ $client->succeed("ping -c 1 192.168.2.1");
+ $client->succeed("ping -c 1 192.168.2.2");
+
+ $router->succeed("ping -c 1 192.168.2.1");
+ $router->succeed("ping -c 1 192.168.2.2");
+ '';
+ };
+ dhcpOneIf = {
+ name = "OneInterfaceDHCP";
+ nodes.router = router;
+ nodes.client = { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 2 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ interfaces.eth1 = {
+ ip4 = mkOverride 0 [ ];
+ useDHCP = true;
+ };
+ interfaces.eth2.ip4 = mkOverride 0 [ ];
+ };
+ };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client->waitForUnit("network-interfaces.target");
+ $client->waitForUnit("network.target");
+ $router->waitForUnit("network-interfaces.target");
+ $router->waitForUnit("network.target");
+
+ # Wait until we have an ip address on each interface
+ $client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
+
+ # Test vlan 1
+ $client->succeed("ping -c 1 192.168.1.1");
+ $client->succeed("ping -c 1 192.168.1.2");
+
+ $router->succeed("ping -c 1 192.168.1.1");
+ $router->succeed("ping -c 1 192.168.1.2");
+
+ # Test vlan 2
+ $client->succeed("ping -c 1 192.168.2.1");
+ $client->fail("ping -c 1 192.168.2.2");
+
+ $router->succeed("ping -c 1 192.168.2.1");
+ $router->fail("ping -c 1 192.168.2.2");
+ '';
+ };
+ bond = let
+ node = address: { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 2 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ bonds.bond = {
+ mode = "balance-rr";
+ interfaces = [ "eth1" "eth2" ];
+ };
+ interfaces.eth1.ip4 = mkOverride 0 [ ];
+ interfaces.eth2.ip4 = mkOverride 0 [ ];
+ interfaces.bond.ip4 = mkOverride 0
+ [ { inherit address; prefixLength = 30; } ];
+ };
+ };
+ in {
+ name = "Bond";
+ nodes.client1 = node "192.168.1.1";
+ nodes.client2 = node "192.168.1.2";
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client1->waitForUnit("network-interfaces.target");
+ $client1->waitForUnit("network.target");
+ $client2->waitForUnit("network-interfaces.target");
+ $client2->waitForUnit("network.target");
+
+ # Test bonding
+ $client1->succeed("ping -c 2 192.168.1.1");
+ $client1->succeed("ping -c 2 192.168.1.2");
+
+ $client2->succeed("ping -c 2 192.168.1.1");
+ $client2->succeed("ping -c 2 192.168.1.2");
+ '';
+ };
+ bridge = let
+ node = { address, vlan }: { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ vlan ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ interfaces.eth1.ip4 = mkOverride 0
+ [ { inherit address; prefixLength = 24; } ];
+ };
+ };
+ in {
+ name = "Bridge";
+ nodes.client1 = node { address = "192.168.1.2"; vlan = 1; };
+ nodes.client2 = node { address = "192.168.1.3"; vlan = 2; };
+ nodes.router = { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 2 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ bridges.bridge.interfaces = [ "eth1" "eth2" ];
+ interfaces.eth1.ip4 = mkOverride 0 [ ];
+ interfaces.eth2.ip4 = mkOverride 0 [ ];
+ interfaces.bridge.ip4 = mkOverride 0
+ [ { address = "192.168.1.1"; prefixLength = 24; } ];
+ };
+ };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client1->waitForUnit("network-interfaces.target");
+ $client1->waitForUnit("network.target");
+ $client2->waitForUnit("network-interfaces.target");
+ $client2->waitForUnit("network.target");
+ $router->waitForUnit("network-interfaces.target");
+ $router->waitForUnit("network.target");
+
+ # Test bridging
+ $client1->succeed("ping -c 1 192.168.1.1");
+ $client1->succeed("ping -c 1 192.168.1.2");
+ $client1->succeed("ping -c 1 192.168.1.3");
+
+ $client2->succeed("ping -c 1 192.168.1.1");
+ $client2->succeed("ping -c 1 192.168.1.2");
+ $client2->succeed("ping -c 1 192.168.1.3");
+
+ $router->succeed("ping -c 1 192.168.1.1");
+ $router->succeed("ping -c 1 192.168.1.2");
+ $router->succeed("ping -c 1 192.168.1.3");
+ '';
+ };
+ macvlan = {
+ name = "MACVLAN";
+ nodes.router = router;
+ nodes.client = { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = true;
+ macvlans.macvlan.interface = "eth1";
+ interfaces.eth1.ip4 = mkOverride 0 [ ];
+ };
+ };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client->waitForUnit("network-interfaces.target");
+ $client->waitForUnit("network.target");
+ $router->waitForUnit("network-interfaces.target");
+ $router->waitForUnit("network.target");
+
+ # Wait until we have an ip address on each interface
+ $client->succeed("while ! ip addr show dev eth1 | grep '192.168.1'; do true; done");
+ $client->succeed("while ! ip addr show dev macvlan | grep '192.168.1'; do true; done");
+
+ # Test macvlan
+ $client->succeed("ping -c 1 192.168.1.1");
+ $client->succeed("ping -c 1 192.168.1.2");
+ $client->succeed("ping -c 1 192.168.1.3");
+
+ $router->succeed("ping -c 1 192.168.1.1");
+ $router->succeed("ping -c 1 192.168.1.2");
+ $router->succeed("ping -c 1 192.168.1.3");
+ '';
+ };
+ sit = let
+ node = { address4, remote, address6 }: { config, pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.enable = false;
+ useDHCP = false;
+ sits.sit = {
+ inherit remote;
+ local = address4;
+ dev = "eth1";
+ };
+ interfaces.eth1.ip4 = mkOverride 0
+ [ { address = address4; prefixLength = 24; } ];
+ interfaces.sit.ip6 = mkOverride 0
+ [ { address = address6; prefixLength = 64; } ];
+ };
+ };
+ in {
+ name = "Sit";
+ nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; };
+ nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; };
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client1->waitForUnit("network-interfaces.target");
+ $client1->waitForUnit("network.target");
+ $client2->waitForUnit("network-interfaces.target");
+ $client2->waitForUnit("network.target");
+
+ $client1->succeed("ip addr >&2");
+ $client2->succeed("ip addr >&2");
+
+ # Test ipv6
+ $client1->succeed("ping6 -c 1 fc00::1");
+ $client1->succeed("ping6 -c 1 fc00::2");
+
+ $client2->succeed("ping6 -c 1 fc00::1");
+ $client2->succeed("ping6 -c 1 fc00::2");
+ '';
+ };
+ vlan = let
+ node = address: { config, pkgs, ... }: with pkgs.lib; {
+ #virtualisation.vlans = [ 1 ];
+ networking = {
+ useNetworkd = networkd;
+ firewall.allowPing = true;
+ useDHCP = false;
+ vlans.vlan = {
+ id = 1;
+ interface = "eth0";
+ };
+ interfaces.eth0.ip4 = mkOverride 0 [ ];
+ interfaces.eth1.ip4 = mkOverride 0 [ ];
+ interfaces.vlan.ip4 = mkOverride 0
+ [ { inherit address; prefixLength = 24; } ];
+ };
+ };
+ in {
+ name = "vlan";
+ nodes.client1 = node "192.168.1.1";
+ nodes.client2 = node "192.168.1.2";
+ testScript = { nodes, ... }:
+ ''
+ startAll;
+
+ $client1->waitForUnit("network-interfaces.target");
+ $client1->waitForUnit("network.target");
+ $client2->waitForUnit("network-interfaces.target");
+ $client2->waitForUnit("network.target");
+
+ # Test vlan is setup
+ $client1->succeed("ip addr show dev vlan >&2");
+ $client2->succeed("ip addr show dev vlan >&2");
+ '';
+ };
+ };
+ case = testCases.${test};
+ in case // {
+ name = "${case.name}-Networking-${if networkd then "Networkd" else "Scripted"}";
+ })
diff --git a/nixos/tests/nfs.nix b/nixos/tests/nfs.nix
index 61b2431c04c..216fea7784a 100644
--- a/nixos/tests/nfs.nix
+++ b/nixos/tests/nfs.nix
@@ -1,4 +1,4 @@
-import ./make-test.nix ({ version, ... }:
+import ./make-test.nix ({ version ? 4, ... }:
let
@@ -38,7 +38,8 @@ in
testScript =
''
$server->waitForUnit("nfsd");
- $server->waitForUnit("network.target");
+ $server->succeed("systemctl start network-online.target");
+ $server->waitForUnit("network-online.target");
startAll;
diff --git a/nixos/tests/nsd.nix b/nixos/tests/nsd.nix
new file mode 100644
index 00000000000..c2331931cdd
--- /dev/null
+++ b/nixos/tests/nsd.nix
@@ -0,0 +1,83 @@
+let
+ common = { pkgs, ... }: {
+ networking.firewall.enable = false;
+ networking.useDHCP = false;
+ # for a host utility with IPv6 support
+ environment.systemPackages = [ pkgs.bind ];
+ };
+in import ./make-test.nix {
+ name = "nsd";
+
+ nodes = {
+ clientv4 = { lib, nodes, ... }: {
+ imports = [ common ];
+ networking.nameservers = lib.mkForce [
+ nodes.server.config.networking.interfaces.eth1.ipAddress
+ ];
+ networking.interfaces.eth1.ipAddress = "192.168.0.2";
+ networking.interfaces.eth1.prefixLength = 24;
+ };
+
+ clientv6 = { lib, nodes, ... }: {
+ imports = [ common ];
+ networking.nameservers = lib.mkForce [
+ nodes.server.config.networking.interfaces.eth1.ipv6Address
+ ];
+ networking.interfaces.eth1.ipv6Address = "dead:beef::2";
+ };
+
+ server = { lib, ... }: {
+ imports = [ common ];
+ networking.interfaces.eth1.ipAddress = "192.168.0.1";
+ networking.interfaces.eth1.prefixLength = 24;
+ networking.interfaces.eth1.ipv6Address = "dead:beef::1";
+ services.nsd.enable = true;
+ services.nsd.interfaces = lib.mkForce [];
+ services.nsd.zones."example.com.".data = ''
+ @ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
+ ipv4 A 1.2.3.4
+ ipv6 AAAA abcd::eeff
+ deleg NS ns.example.com
+ ns A 192.168.0.1
+ ns AAAA dead:beef::1
+ '';
+ services.nsd.zones."deleg.example.com.".data = ''
+ @ SOA ns.example.com noc.example.com 666 7200 3600 1209600 3600
+ @ A 9.8.7.6
+ @ AAAA fedc::bbaa
+ '';
+ };
+ };
+
+ testScript = ''
+ startAll;
+
+ $clientv4->waitForUnit("network.target");
+ $clientv6->waitForUnit("network.target");
+ $server->waitForUnit("nsd.service");
+
+ sub assertHost {
+ my ($type, $rr, $query, $expected) = @_;
+ my $self = $type eq 4 ? $clientv4 : $clientv6;
+ my $out = $self->succeed("host -$type -t $rr $query");
+ $self->log("output: $out");
+ chomp $out;
+ die "DNS IPv$type query on $query gave '$out' instead of '$expected'"
+ if ($out !~ $expected);
+ }
+
+ foreach (4, 6) {
+ subtest "ipv$_", sub {
+ assertHost($_, "a", "example.com", qr/has no [^ ]+ record/);
+ assertHost($_, "aaaa", "example.com", qr/has no [^ ]+ record/);
+
+ assertHost($_, "soa", "example.com", qr/SOA.*?noc\.example\.com/);
+ assertHost($_, "a", "ipv4.example.com", qr/address 1.2.3.4$/);
+ assertHost($_, "aaaa", "ipv6.example.com", qr/address abcd::eeff$/);
+
+ assertHost($_, "a", "deleg.example.com", qr/address 9.8.7.6$/);
+ assertHost($_, "aaaa", "deleg.example.com", qr/address fedc::bbaa$/);
+ };
+ }
+ '';
+}
diff --git a/nixos/tests/panamax.nix b/nixos/tests/panamax.nix
new file mode 100644
index 00000000000..80af8a19be1
--- /dev/null
+++ b/nixos/tests/panamax.nix
@@ -0,0 +1,18 @@
+import ./make-test.nix {
+ name = "panamax";
+
+ machine = { config, pkgs, ... }: {
+ services.panamax.enable = true;
+ };
+
+ testScript =
+ ''
+ startAll;
+ $machine->waitForUnit("panamax-api.service");
+ $machine->waitForUnit("panamax-ui.service");
+ $machine->waitForOpenPort(3000);
+ $machine->waitForOpenPort(8888);
+ $machine->succeed("curl --fail http://localhost:8888/ > /dev/null");
+ $machine->shutdown;
+ '';
+}
diff --git a/nixos/tests/partition.nix b/nixos/tests/partition.nix
index 72fd37e041e..5e94b263d5b 100644
--- a/nixos/tests/partition.nix
+++ b/nixos/tests/partition.nix
@@ -67,7 +67,7 @@ in {
machine = { config, pkgs, ... }: {
environment.systemPackages = [
- pkgs.pythonPackages.nixpart
+ pkgs.pythonPackages.nixpart0
pkgs.file pkgs.btrfsProgs pkgs.xfsprogs pkgs.lvm2
];
virtualisation.emptyDiskImages = [ 4096 4096 ];
@@ -209,7 +209,7 @@ in {
ensurePartition("swap", "swap");
ensurePartition("boot", "f2fs");
ensurePartition("root", "f2fs");
- remoteAndCheck;
+ remountAndCheck;
ensureMountPoint("/mnt/boot", "f2fs");
};
diff --git a/nixos/tests/peerflix.nix b/nixos/tests/peerflix.nix
new file mode 100644
index 00000000000..739936a10b2
--- /dev/null
+++ b/nixos/tests/peerflix.nix
@@ -0,0 +1,21 @@
+# This test runs peerflix and checks if peerflix starts
+
+import ./make-test.nix {
+ name = "peerflix";
+
+ nodes = {
+ peerflix =
+ { config, pkgs, ... }:
+ {
+ services.peerflix.enable = true;
+ };
+ };
+
+ testScript = ''
+ startAll;
+
+ $peerflix->waitForUnit("peerflix.service");
+ $peerflix->waitUntilSucceeds("curl localhost:9000");
+ '';
+
+}
diff --git a/nixos/tests/phabricator.nix b/nixos/tests/phabricator.nix
index 53038474c91..0fe31f66502 100644
--- a/nixos/tests/phabricator.nix
+++ b/nixos/tests/phabricator.nix
@@ -32,9 +32,16 @@ import ./make-test.nix ({ pkgs, ... }: {
}];
};
+ phd = {
+ enable = true;
+ };
+
mysql = {
enable = true;
package = pkgs.mysql;
+ extraOptions = ''
+ sql_mode=STRICT_ALL_TABLES
+ '';
};
};
diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix
index a55e077c269..ba10f23582d 100644
--- a/nixos/tests/printing.nix
+++ b/nixos/tests/printing.nix
@@ -9,7 +9,7 @@ import ./make-test.nix ({pkgs, ... }: {
{ config, pkgs, ... }:
{ services.printing.enable = true;
services.printing.listenAddresses = [ "*:631" ];
- services.printing.cupsdConf =
+ services.printing.extraConf =
''
Order allow,deny
@@ -31,8 +31,8 @@ import ./make-test.nix ({pkgs, ... }: {
startAll;
# Make sure that cups is up on both sides.
- $server->waitForUnit("cupsd.service");
- $client->waitForUnit("cupsd.service");
+ $server->waitForUnit("cups.service");
+ $client->waitForUnit("cups.service");
$client->succeed("lpstat -r") =~ /scheduler is running/ or die;
$client->succeed("lpstat -H") =~ "/var/run/cups/cups.sock" or die;
$client->succeed("curl --fail http://localhost:631/");
@@ -40,10 +40,10 @@ import ./make-test.nix ({pkgs, ... }: {
$server->fail("curl --fail --connect-timeout 2 http://client:631/");
# Add a HP Deskjet printer connected via USB to the server.
- $server->succeed("lpadmin -p DeskjetLocal -v usb://HP/Deskjet%205400%20series?serial=TH93I152S123XY -m 'drv:///sample.drv/deskjet.ppd' -E");
+ $server->succeed("lpadmin -p DeskjetLocal -E -v usb://foobar/printers/foobar");
# Add it to the client as well via IPP.
- $client->succeed("lpadmin -p DeskjetRemote -v ipp://server/printers/DeskjetLocal -m 'drv:///sample.drv/deskjet.ppd' -E");
+ $client->succeed("lpadmin -p DeskjetRemote -E -v ipp://server/printers/DeskjetLocal");
$client->succeed("lpadmin -d DeskjetRemote");
# Do some status checks.
@@ -55,10 +55,10 @@ import ./make-test.nix ({pkgs, ... }: {
$client->succeed("lpq") =~ /DeskjetRemote is ready.*no entries/s or die;
# Test printing various file types.
- foreach my $file ("${pkgs.groff}/share/doc/*/examples/mom/typesetting.pdf",
+ foreach my $file ("${pkgs.groff}/share/doc/*/examples/mom/penguin.pdf",
"${pkgs.groff}/share/doc/*/meref.ps",
"${pkgs.cups}/share/doc/cups/images/cups.png",
- "${pkgs.xz}/share/doc/xz/faq.txt")
+ "${pkgs.pcre}/share/doc/pcre/pcre.txt")
{
$file =~ /([^\/]*)$/; my $fn = $1;
@@ -72,9 +72,8 @@ import ./make-test.nix ({pkgs, ... }: {
# (showing that the right filters have been applied). Of
# course, since there is no actual USB printer attached, the
# file will stay in the queue forever.
- $server->waitForFile("/var/spool/cups/d*-*");
- $server->succeed("lpq -a") =~ /remroot.*$fn/ or die;
- $server->succeed("hexdump -C -n2 /var/spool/cups/d*-*") =~ /1b 45/ or die; # 1b 45 = printer reset
+ $server->waitForFile("/var/spool/cups/d00001-001");
+ $server->succeed("lpq -a") =~ /$fn/ or die;
# Delete the job on the client. It should disappear on the
# server as well.
diff --git a/nixos/tests/proxy.nix b/nixos/tests/proxy.nix
index 01f0f3fe17a..8350bc5c6a4 100644
--- a/nixos/tests/proxy.nix
+++ b/nixos/tests/proxy.nix
@@ -22,20 +22,19 @@ in
{ services.httpd.enable = true;
services.httpd.adminAddr = "bar@example.org";
- services.httpd.extraModules = ["proxy_balancer"];
+ services.httpd.extraModules = [ "proxy_balancer" "lbmethod_byrequests" ];
services.httpd.extraConfig =
''
ExtendedStatus on
- Order deny,allow
- Allow from all
+ Require all granted
SetHandler server-status
- Allow from all
+ Require all granted
BalancerMember http://${nodes.backend1.config.networking.hostName} retry=0
BalancerMember http://${nodes.backend2.config.networking.hostName} retry=0
diff --git a/nixos/tests/quake3.nix b/nixos/tests/quake3.nix
index b16cb179982..e0e6d6eaadb 100644
--- a/nixos/tests/quake3.nix
+++ b/nixos/tests/quake3.nix
@@ -15,14 +15,14 @@ in
rec {
name = "quake3";
- makeCoverageReport = true;
+ # TODO: lcov doesn't work atm
+ #makeCoverageReport = true;
client =
{ config, pkgs, ... }:
{ imports = [ ./common/x11.nix ];
hardware.opengl.driSupport = true;
- services.xserver.defaultDepth = pkgs.lib.mkOverride 0 16;
environment.systemPackages = [ pkgs.quake3demo ];
nixpkgs.config.packageOverrides = overrides;
};
diff --git a/nixos/tests/run-in-machine.nix b/nixos/tests/run-in-machine.nix
index 7f6e6a6dc57..d1102f8d407 100644
--- a/nixos/tests/run-in-machine.nix
+++ b/nixos/tests/run-in-machine.nix
@@ -2,9 +2,7 @@
with import ../lib/testing.nix { inherit system; };
-{
- test = runInMachine {
- drv = pkgs.hello;
- machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
- };
+runInMachine {
+ drv = pkgs.hello;
+ machine = { config, pkgs, ... }: { /* services.sshd.enable = true; */ };
}
diff --git a/nixos/tests/virtualbox.nix b/nixos/tests/virtualbox.nix
new file mode 100644
index 00000000000..827481879a3
--- /dev/null
+++ b/nixos/tests/virtualbox.nix
@@ -0,0 +1,403 @@
+import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
+
+ debug = false;
+
+ testVMConfig = vmName: attrs: { config, pkgs, ... }: {
+ boot.kernelParams = let
+ miniInit = ''
+ #!${pkgs.stdenv.shell} -xe
+ export PATH="${pkgs.coreutils}/bin:${pkgs.utillinux}/bin"
+
+ ${pkgs.linuxPackages.virtualboxGuestAdditions}/sbin/VBoxService
+ ${(attrs.vmScript or (const "")) pkgs}
+
+ i=0
+ while [ ! -e /mnt-root/shutdown ]; do
+ sleep 10
+ i=$(($i + 10))
+ [ $i -le 120 ] || fail
+ done
+
+ rm -f /mnt-root/boot-done /mnt-root/shutdown
+ '';
+ in [
+ "console=tty0" "console=ttyS0" "ignore_loglevel"
+ "boot.trace" "panic=1" "boot.panic_on_fail"
+ "init=${pkgs.writeScript "mini-init.sh" miniInit}"
+ ];
+
+ fileSystems."/" = {
+ device = "vboxshare";
+ fsType = "vboxsf";
+ };
+
+ services.virtualboxGuest.enable = true;
+
+ boot.initrd.kernelModules = [
+ "af_packet" "vboxsf"
+ "virtio" "virtio_pci" "virtio_ring" "virtio_net" "vboxguest"
+ ];
+
+ boot.initrd.extraUtilsCommands = ''
+ copy_bin_and_libs "${pkgs.linuxPackages.virtualboxGuestAdditions}/sbin/mount.vboxsf"
+ copy_bin_and_libs "${pkgs.utillinux}/bin/unshare"
+ ${(attrs.extraUtilsCommands or (const "")) pkgs}
+ '';
+
+ boot.initrd.postMountCommands = ''
+ touch /mnt-root/boot-done
+ hostname "${vmName}"
+ mkdir -p /nix/store
+ unshare -m "@shell@" -c '
+ mount -t vboxsf nixstore /nix/store
+ exec "$stage2Init"
+ '
+ poweroff -f
+ '';
+
+ system.requiredKernelConfig = with config.lib.kernelConfig; [
+ (isYes "SERIAL_8250_CONSOLE")
+ (isYes "SERIAL_8250")
+ ];
+ };
+
+ mkLog = logfile: tag: let
+ rotated = map (i: "${logfile}.${toString i}") (range 1 9);
+ all = concatMapStringsSep " " (f: "\"${f}\"") ([logfile] ++ rotated);
+ logcmd = "tail -F ${all} 2> /dev/null | logger -t \"${tag}\"";
+ in optionalString debug "$machine->execute(ru '${logcmd} & disown');";
+
+ testVM = vmName: vmScript: let
+ cfg = (import ../lib/eval-config.nix {
+ system = "i686-linux";
+ modules = [
+ ../modules/profiles/minimal.nix
+ (testVMConfig vmName vmScript)
+ ];
+ }).config;
+ in pkgs.vmTools.runInLinuxVM (pkgs.runCommand "virtualbox-image" {
+ preVM = ''
+ mkdir -p "$out"
+ diskImage="$(pwd)/qimage"
+ ${pkgs.vmTools.qemu}/bin/qemu-img create -f raw "$diskImage" 100M
+ '';
+
+ postVM = ''
+ echo "creating VirtualBox disk image..."
+ ${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi \
+ "$diskImage" "$out/disk.vdi"
+ '';
+
+ buildInputs = [ pkgs.utillinux pkgs.perl ];
+ } ''
+ ${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
+ ${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
+ . /sys/class/block/vda1/uevent
+ mknod /dev/vda1 b $MAJOR $MINOR
+
+ ${pkgs.e2fsprogs}/sbin/mkfs.ext4 /dev/vda1
+ ${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
+ mkdir /mnt
+ mount /dev/vda1 /mnt
+ cp "${cfg.system.build.kernel}/bzImage" /mnt/linux
+ cp "${cfg.system.build.initialRamdisk}/initrd" /mnt/initrd
+
+ ${pkgs.grub2}/bin/grub-install --boot-directory=/mnt /dev/vda
+
+ cat > /mnt/grub/grub.cfg <execute(ru $cmd);
+ return $status == 0;
+ }
+
+ sub cleanup_${name} {
+ $machine->execute(ru "VBoxManage controlvm ${name} poweroff")
+ if checkRunning_${name};
+ $machine->succeed("rm -rf ${sharePath}");
+ $machine->succeed("mkdir -p ${sharePath}");
+ $machine->succeed("chown alice.users ${sharePath}");
+ }
+
+ sub createVM_${name} {
+ vbm("createvm --name ${name} ${createFlags}");
+ vbm("modifyvm ${name} ${vmFlags}");
+ vbm("setextradata ${name} VBoxInternal/PDM/HaltOnReset 1");
+ vbm("storagectl ${name} ${controllerFlags}");
+ vbm("storageattach ${name} ${diskFlags}");
+ vbm("sharedfolder add ${name} ${sharedFlags}");
+ vbm("sharedfolder add ${name} ${nixstoreFlags}");
+ cleanup_${name};
+
+ ${mkLog "$HOME/VirtualBox VMs/${name}/Logs/VBox.log" "HOST-${name}"}
+ }
+
+ sub destroyVM_${name} {
+ cleanup_${name};
+ vbm("unregistervm ${name} --delete");
+ }
+
+ sub waitForVMBoot_${name} {
+ $machine->execute(ru(
+ 'set -e; i=0; '.
+ 'while ! test -e ${sharePath}/boot-done; do '.
+ 'sleep 10; i=$(($i + 10)); [ $i -le 3600 ]; '.
+ 'VBoxManage list runningvms | grep -q "^\"${name}\""; '.
+ 'done'
+ ));
+ }
+
+ sub waitForIP_${name} ($) {
+ my $property = "/VirtualBox/GuestInfo/Net/$_[0]/V4/IP";
+ my $getip = "VBoxManage guestproperty get ${name} $property | ".
+ "sed -n -e 's/^Value: //p'";
+ my $ip = $machine->succeed(ru(
+ 'for i in $(seq 1000); do '.
+ 'if ipaddr="$('.$getip.')" && [ -n "$ipaddr" ]; then '.
+ 'echo "$ipaddr"; exit 0; '.
+ 'fi; '.
+ 'sleep 1; '.
+ 'done; '.
+ 'echo "Could not get IPv4 address for ${name}!" >&2; '.
+ 'exit 1'
+ ));
+ chomp $ip;
+ return $ip;
+ }
+
+ sub waitForStartup_${name} {
+ for (my $i = 0; $i <= 120; $i += 10) {
+ $machine->sleep(10);
+ return if checkRunning_${name};
+ eval { $_[0]->() } if defined $_[0];
+ }
+ die "VirtualBox VM didn't start up within 2 minutes";
+ }
+
+ sub waitForShutdown_${name} {
+ for (my $i = 0; $i <= 120; $i += 10) {
+ $machine->sleep(10);
+ return unless checkRunning_${name};
+ }
+ die "VirtualBox VM didn't shut down within 2 minutes";
+ }
+
+ sub shutdownVM_${name} {
+ $machine->succeed(ru "touch ${sharePath}/shutdown");
+ $machine->waitUntilSucceeds(
+ "test ! -e ${sharePath}/shutdown ".
+ " -a ! -e ${sharePath}/boot-done"
+ );
+ waitForShutdown_${name};
+ }
+ '';
+ };
+
+ hostonlyVMFlags = [
+ "--nictype1 virtio"
+ "--nictype2 virtio"
+ "--nic2 hostonly"
+ "--hostonlyadapter2 vboxnet0"
+ ];
+
+ dhcpScript = pkgs: ''
+ ${pkgs.dhcp}/bin/dhclient \
+ -lf /run/dhcp.leases \
+ -pf /run/dhclient.pid \
+ -v eth0 eth1
+
+ otherIP="$(${pkgs.netcat}/bin/netcat -clp 1234 || :)"
+ ${pkgs.iputils}/bin/ping -I eth1 -c1 "$otherIP"
+ echo "$otherIP reachable" | ${pkgs.netcat}/bin/netcat -clp 5678 || :
+ '';
+
+ vboxVMs = mapAttrs createVM {
+ simple = {};
+
+ test1.vmFlags = hostonlyVMFlags;
+ test1.vmScript = dhcpScript;
+
+ test2.vmFlags = hostonlyVMFlags;
+ test2.vmScript = dhcpScript;
+ };
+
+in {
+ name = "virtualbox";
+
+ machine = { pkgs, lib, config, ... }: {
+ imports = let
+ mkVMConf = name: val: val.machine // { key = "${name}-config"; };
+ vmConfigs = mapAttrsToList mkVMConf vboxVMs;
+ in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
+ virtualisation.memorySize = 768;
+ services.virtualboxHost.enable = true;
+ users.extraUsers.alice.extraGroups = let
+ inherit (config.services.virtualboxHost) enableHardening;
+ in lib.mkIf enableHardening (lib.singleton "vboxusers");
+ };
+
+ testScript = ''
+ sub ru ($) {
+ my $esc = $_[0] =~ s/'/'\\${"'"}'/gr;
+ return "su - alice -c '$esc'";
+ }
+
+ sub vbm {
+ $machine->succeed(ru("VBoxManage ".$_[0]));
+ };
+
+ ${concatStrings (mapAttrsToList (_: getAttr "testSubs") vboxVMs)}
+
+ $machine->waitForX;
+
+ ${mkLog "$HOME/.config/VirtualBox/VBoxSVC.log" "HOST-SVC"}
+
+ createVM_simple;
+
+ subtest "simple-gui", sub {
+ $machine->succeed(ru "VirtualBox &");
+ $machine->waitForWindow(qr/Oracle VM VirtualBox Manager/);
+ $machine->sleep(5);
+ $machine->screenshot("gui_manager_started");
+ $machine->sendKeys("ret");
+ $machine->screenshot("gui_manager_sent_startup");
+ waitForStartup_simple (sub {
+ $machine->sendKeys("ret");
+ });
+ $machine->screenshot("gui_started");
+ waitForVMBoot_simple;
+ $machine->screenshot("gui_booted");
+ shutdownVM_simple;
+ $machine->sleep(5);
+ $machine->screenshot("gui_stopped");
+ $machine->sendKeys("ctrl-q");
+ $machine->sleep(5);
+ $machine->screenshot("gui_manager_stopped");
+ };
+
+ cleanup_simple;
+
+ subtest "simple-cli", sub {
+ vbm("startvm simple");
+ waitForStartup_simple;
+ $machine->screenshot("cli_started");
+ waitForVMBoot_simple;
+ $machine->screenshot("cli_booted");
+ shutdownVM_simple;
+ };
+
+ subtest "privilege-escalation", sub {
+ $machine->fail("test -e '/root/VirtualBox VMs'");
+ $machine->fail("test -e '/root/.config/VirtualBox'");
+ $machine->succeed("test -e '/home/alice/VirtualBox VMs'");
+ };
+
+ destroyVM_simple;
+
+ subtest "net-hostonlyif", sub {
+ createVM_test1;
+ createVM_test2;
+
+ vbm("startvm test1");
+ waitForStartup_test1;
+
+ vbm("startvm test2");
+ waitForStartup_test2;
+
+ waitForVMBoot_test1;
+ waitForVMBoot_test2;
+
+ $machine->screenshot("net_booted");
+
+ my $test1IP = waitForIP_test1 1;
+ my $test2IP = waitForIP_test2 1;
+
+ $machine->succeed("echo '$test2IP' | netcat -c '$test1IP' 1234");
+ $machine->succeed("echo '$test1IP' | netcat -c '$test2IP' 1234");
+
+ $machine->waitUntilSucceeds("netcat -c '$test1IP' 5678 >&2");
+ $machine->waitUntilSucceeds("netcat -c '$test2IP' 5678 >&2");
+
+ shutdownVM_test1;
+ shutdownVM_test2;
+
+ destroyVM_test1;
+ destroyVM_test2;
+ };
+ '';
+})
diff --git a/pkgs/applications/altcoins/bitcoin.nix b/pkgs/applications/altcoins/bitcoin.nix
new file mode 100644
index 00000000000..0e98e234214
--- /dev/null
+++ b/pkgs/applications/altcoins/bitcoin.nix
@@ -0,0 +1,38 @@
+{ stdenv, fetchurl, pkgconfig, autoreconfHook, openssl, db48, boost
+, zlib, miniupnpc, qt4, utillinux, protobuf, qrencode
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec{
+
+ name = "bitcoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "0.10.0";
+
+ src = fetchurl {
+ url = [ "https://bitcoin.org/bin/bitcoin-core-0.10.0/bitcoin-${version}.tar.gz"
+ "mirror://sourceforge/bitcoin/Bitcoin/bitcoin-0.10.0/bitcoin-${version}.tar.gz"
+ ];
+ sha256 = "a516cf6d9f58a117607148405334b35d3178df1ba1c59229609d2bcd08d30624";
+ };
+
+ buildInputs = [ pkgconfig autoreconfHook openssl db48 boost zlib
+ miniupnpc utillinux protobuf ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ configureFlags = [ "--with-boost-libdir=${boost.lib}/lib" ]
+ ++ optionals withGui [ "--with-gui=qt4" ];
+
+ meta = {
+ description = "Peer-to-peer electronic cash system";
+ longDescription= ''
+ Bitcoin is a free open source peer-to-peer electronic cash system that is
+ completely decentralized, without the need for a central server or trusted
+ parties. Users hold the crypto keys to their own money and transact directly
+ with each other, with the help of a P2P network to check for double-spending.
+ '';
+ homepage = "http://www.bitcoin.org/";
+ maintainers = with maintainers; [ roconnor AndersonTorres ];
+ license = licenses.mit;
+ platforms = platforms.unix;
+ };
+}
diff --git a/pkgs/applications/altcoins/darkcoin.nix b/pkgs/applications/altcoins/darkcoin.nix
new file mode 100644
index 00000000000..56d22d0b53b
--- /dev/null
+++ b/pkgs/applications/altcoins/darkcoin.nix
@@ -0,0 +1,40 @@
+{ fetchurl, stdenv, pkgconfig
+, openssl, db48, boost, zlib, miniupnpc, qt4, qrencode, glib, protobuf
+, utillinux
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec {
+
+ name = "darkcoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "0.10.99.99";
+
+ src = fetchurl {
+ url = "https://github.com/darkcoin/darkcoin/archive/v${version}.tar.gz";
+ sha256 = "1a05a7l878klg4wqk9ykndkhyknrd7jp75v38k99qgk5fi8wa752";
+ };
+
+ buildInputs = [ pkgconfig glib openssl db48 boost zlib miniupnpc ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ configurePhase = optional withGui "qmake";
+
+ preBuild = optional (!withGui) "cd src; cp makefile.unix Makefile";
+
+ installPhase =
+ if withGui
+ then "install -D darkcoin-qt $out/bin/darkcoin-qt"
+ else "install -D darkcoind $out/bin/darkcoind";
+
+ meta = with stdenv.lib; {
+ description = "A decentralized key/value registration and transfer system";
+ longDescription = ''
+ Darkcoin (DRK) is an open sourced, privacy-centric digital
+ currency. It allows you keep your finances private as you make
+ transactions, similar to cash.
+ '';
+ homepage = http://darkcoin.io;
+ maintainers = with maintainers; [ AndersonTorres ];
+ platforms = with platforms; unix;
+ };
+}
diff --git a/pkgs/applications/altcoins/default.nix b/pkgs/applications/altcoins/default.nix
new file mode 100644
index 00000000000..a49e4dc9f90
--- /dev/null
+++ b/pkgs/applications/altcoins/default.nix
@@ -0,0 +1,26 @@
+{ callPackage, pkgs }:
+
+rec {
+
+ bitcoin = callPackage ./bitcoin.nix { withGui = true; };
+ bitcoind = callPackage ./bitcoin.nix { withGui = false; };
+
+ darkcoin = callPackage ./darkcoin.nix { withGui = true; };
+ darkcoind = callPackage ./darkcoin.nix { withGui = false; };
+
+ dogecoin = callPackage ./dogecoin.nix { withGui = true; };
+ dogecoind = callPackage ./dogecoin.nix { withGui = false; };
+
+ litecoin = callPackage ./litecoin.nix { withGui = true; };
+ litecoind = callPackage ./litecoin.nix { withGui = false; };
+
+ memorycoin = callPackage ./memorycoin.nix { withGui = true; };
+ memorycoind = callPackage ./memorycoin.nix { withGui = false; };
+
+ namecoin = callPackage ./namecoin.nix { inherit namecoind; };
+ namecoind = callPackage ./namecoind.nix { };
+
+ primecoin = callPackage ./primecoin.nix { withGui = true; };
+ primecoind = callPackage ./primecoin.nix { withGui = false; };
+
+}
diff --git a/pkgs/applications/altcoins/dogecoin.nix b/pkgs/applications/altcoins/dogecoin.nix
new file mode 100644
index 00000000000..cf2f25bfeee
--- /dev/null
+++ b/pkgs/applications/altcoins/dogecoin.nix
@@ -0,0 +1,47 @@
+{ stdenv , fetchurl
+, pkgconfig, autoreconfHook
+, db5, openssl, boost, zlib, miniupnpc
+, glib, protobuf, utillinux, qt4, qrencode
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec {
+
+ name = "dogecoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "1.8.2";
+
+ src = fetchurl {
+ url = "https://github.com/dogecoin/dogecoin/archive/v${version}.tar.gz";
+ sha256 = "17jxsxsrsz3qy2hxdpw78vcbnnd0nq614iy42ypzhw4pdpz0s1l7";
+ };
+
+ buildInputs = [ autoreconfHook pkgconfig openssl
+ db5 openssl utillinux protobuf boost zlib miniupnpc ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ # BSD DB5 location
+ patchPhase = ''
+ sed -i \
+ -e 's,BDB_CPPFLAGS=$,BDB_CPPFLAGS="-I${db5}/include",g' \
+ -e 's,BDB_LIBS=$,BDB_LIBS="-L${db5}/lib",g' \
+ -e 's,bdbdirlist=$,bdbdirlist="${db5}/include",g' \
+ src/m4/dogecoin_find_bdb51.m4
+ '';
+
+ configureFlags = [ "--with-incompatible-bdb"
+ "--with-boost-libdir=${boost.lib}/lib" ]
+ ++ optionals withGui [ "--with-gui" ];
+
+ meta = {
+ description = "Wow, such coin, much shiba, very rich";
+ longDescription = ''
+ Dogecoin is a decentralized, peer-to-peer digital currency that
+ enables you to easily send money online. Think of it as "the
+ internet currency."
+ It is named after a famous Internet meme, the "Doge" - a Shiba Inu dog.
+ '';
+ homepage = http://www.dogecoin.com/;
+ license = licenses.mit;
+ maintainers = with maintainers; [ edwtjo offline AndersonTorres ];
+ };
+}
diff --git a/pkgs/applications/altcoins/litecoin.nix b/pkgs/applications/altcoins/litecoin.nix
new file mode 100644
index 00000000000..f2235abaaae
--- /dev/null
+++ b/pkgs/applications/altcoins/litecoin.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchurl
+, pkgconfig, autoreconfHook
+, openssl, db48, boost, zlib, miniupnpc
+, glib, protobuf, utillinux, qt4, qrencode
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec {
+
+ name = "litecoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "0.9.3-preview5";
+
+ src = fetchurl {
+ url = "https://github.com/litecoin-project/litecoin/archive/v${version}.tar.gz";
+ sha256 = "0nnfz4s2g28jb5fqy6cabsryp3h2amzlyslr6g6k8r1vmzvx5ym6";
+ };
+
+ buildInputs = [ pkgconfig autoreconfHook openssl
+ openssl db48 boost zlib miniupnpc glib protobuf utillinux ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ configureFlags = [ "--with-boost-libdir=${boost.lib}/lib" ]
+ ++ optionals withGui [ "--with-gui=qt4" ];
+
+ meta = with stdenv.lib; {
+ description = "A lite version of Bitcoin using scrypt as a proof-of-work algorithm";
+ longDescription= ''
+ Litecoin is a peer-to-peer Internet currency that enables instant payments
+ to anyone in the world. It is based on the Bitcoin protocol but differs
+ from Bitcoin in that it can be efficiently mined with consumer-grade hardware.
+ Litecoin provides faster transaction confirmations (2.5 minutes on average)
+ and uses a memory-hard, scrypt-based mining proof-of-work algorithm to target
+ the regular computers and GPUs most people already have.
+ The Litecoin network is scheduled to produce 84 million currency units.
+ '';
+ homepage = https://litecoin.org/;
+ platforms = platforms.unix;
+ license = licenses.mit;
+ maintainers = with maintainers; [ offline AndersonTorres ];
+ };
+}
diff --git a/pkgs/applications/altcoins/memorycoin.nix b/pkgs/applications/altcoins/memorycoin.nix
new file mode 100644
index 00000000000..4e5e24e3062
--- /dev/null
+++ b/pkgs/applications/altcoins/memorycoin.nix
@@ -0,0 +1,50 @@
+{ stdenv, fetchurl, pkgconfig, openssl, db48, boost
+, zlib, miniupnpc, qt4, utillinux, protobuf, qrencode
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec{
+
+ name = "memorycoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "0.8.5";
+
+ src = fetchurl {
+ url = "https://github.com/memorycoin/memorycoin/archive/v${version}.tar.gz";
+ sha256 = "1iyh6dqrg0mirwci5br5n5qw3ghp2cs23wd8ygr56bh9ml4dr1m8";
+ };
+
+ buildInputs = [ pkgconfig openssl db48 boost zlib
+ miniupnpc utillinux protobuf ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ configureFlags = [ "--with-boost-libdir=${boost.lib}/lib" ]
+ ++ optionals withGui [ "--with-gui=qt4" ];
+
+ configurePhase = optional withGui "qmake";
+
+ preBuild = optional (!withGui) "cd src; cp makefile.unix Makefile";
+
+ installPhase =
+ if withGui
+ then "install -D bitcoin-qt $out/bin/memorycoin-qt"
+ else "install -D bitcoind $out/bin/memorycoind";
+
+ meta = {
+ description = "Peer-to-peer, CPU-based electronic cash system";
+ longDescription= ''
+ Memorycoin is a cryptocurrency that aims to empower the
+ economically and financially marginalized. It allows individuals
+ to participate in the internet economy even when they live in
+ countries where credit card companies and PayPal(R) refuse to
+ operate. Individuals can store and transfer wealth with just a
+ memorized pass phrase.
+
+ Memorycoin is based on the Bitcoin code, but with some key
+ differences.
+ '';
+ homepage = "http://www.bitcoin.org/";
+ maintainers = with maintainers; [ AndersonTorres ];
+ license = licenses.mit;
+ platforms = platforms.unix;
+ };
+}
diff --git a/pkgs/applications/altcoins/namecoin.nix b/pkgs/applications/altcoins/namecoin.nix
new file mode 100644
index 00000000000..f2e2aae698e
--- /dev/null
+++ b/pkgs/applications/altcoins/namecoin.nix
@@ -0,0 +1,26 @@
+{ stdenv, db4, boost, openssl, qt4, miniupnpc, unzip, namecoind }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec {
+
+ name = "namecoin-${version}";
+ version = namecoind.version;
+ src = namecoind.src;
+
+ buildInputs = [ db4 boost openssl unzip qt4 miniupnpc ];
+
+ configurePhase = ''
+ qmake USE_UPNP=-
+ '';
+
+ buildPhase = ''
+ make
+ '';
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp namecoin-qt $out/bin
+ '';
+
+ meta = namecoind.meta;
+}
diff --git a/pkgs/applications/altcoins/namecoind.nix b/pkgs/applications/altcoins/namecoind.nix
new file mode 100644
index 00000000000..baf6ba0dbc0
--- /dev/null
+++ b/pkgs/applications/altcoins/namecoind.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchurl, db4, boost, openssl, miniupnpc, unzip }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec {
+ version = "0.3.80";
+ name = "namecoind-${version}";
+
+ src = fetchurl {
+ url = "https://github.com/namecoin/namecoin/archive/nc${version}.tar.gz";
+ sha256 = "1755mqxpg91wg9hf0ibpj59sdzfmhh73yrpi7hfi2ipabkwmlpiz";
+ };
+
+ buildInputs = [ db4 boost openssl unzip miniupnpc ];
+
+ patchPhase = ''
+ sed -e 's/-Wl,-Bstatic//g' -e 's/-l gthread-2.0//g' -e 's/-l z//g' -i src/Makefile
+ '';
+
+ buildPhase = ''
+ make -C src INCLUDEPATHS= LIBPATHS=
+ '';
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp src/namecoind $out/bin
+ '';
+
+ meta = {
+ description = "Decentralized open source information registration and transfer system based on the Bitcoin cryptocurrency";
+ homepage = http://namecoin.info;
+ license = licenses.mit;
+ maintainers = with maintainers; [ doublec AndersonTorres ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/altcoins/primecoin.nix b/pkgs/applications/altcoins/primecoin.nix
new file mode 100644
index 00000000000..11ec35a71bd
--- /dev/null
+++ b/pkgs/applications/altcoins/primecoin.nix
@@ -0,0 +1,52 @@
+{ stdenv, fetchurl, pkgconfig, openssl, db48, boost
+, zlib, miniupnpc, qt4, utillinux, protobuf, qrencode
+, withGui }:
+
+with stdenv.lib;
+stdenv.mkDerivation rec{
+
+ name = "primecoin" + (toString (optional (!withGui) "d")) + "-" + version;
+ version = "0.8.6";
+
+ src = fetchurl {
+ url = "https://github.com/primecoin/primecoin/archive/v${version}.tar.gz";
+ sha256 = "0cixnkici74204s9d5iqj5sccib5a8dig2p2fp1axdjifpg787i3";
+ };
+
+ buildInputs = [ pkgconfig openssl db48 boost zlib
+ miniupnpc utillinux protobuf ]
+ ++ optionals withGui [ qt4 qrencode ];
+
+ configureFlags = [ "--with-boost-libdir=${boost.lib}/lib" ]
+ ++ optionals withGui [ "--with-gui=qt4" ];
+
+ configurePhase = optional withGui "qmake";
+
+ preBuild = optional (!withGui) "cd src; cp makefile.unix Makefile";
+
+ installPhase =
+ if withGui
+ then "install -D bitcoin-qt $out/bin/primecoin-qt"
+ else "install -D bitcoind $out/bin/primecoind";
+
+ meta = {
+ description = "A new type cryptocurrency which is proof-of-work based on searching for prime numbers.";
+ longDescription= ''
+ Primecoin is an innovative cryptocurrency, a form of digital
+ currency secured by cryptography and issued through a
+ decentralized mining market. Derived from Satoshi Nakamoto's
+ Bitcoin, Primecoin introduces an unique form of proof-of-work
+ based on prime numbers.
+
+ The innovative prime proof-of-work in Primecoin not only
+ provides security and minting to the network, but also generates
+ a special form of prime number chains of interest to mathematical
+ research. Thus primecoin network is energy-multiuse, compared to
+ bitcoin.
+ '';
+ homepage = http://primecoin.io/;
+ maintainers = with maintainers; [ AndersonTorres ];
+ license = licenses.mit;
+ platforms = platforms.unix;
+ };
+}
diff --git a/pkgs/applications/audio/a2jmidid/default.nix b/pkgs/applications/audio/a2jmidid/default.nix
index 38192311ccf..218a0f8c6d9 100644
--- a/pkgs/applications/audio/a2jmidid/default.nix
+++ b/pkgs/applications/audio/a2jmidid/default.nix
@@ -1,4 +1,5 @@
-{ stdenv, fetchurl, alsaLib, dbus, jack2, pkgconfig, python }:
+{ stdenv, fetchurl, makeWrapper, pkgconfig, alsaLib, dbus, jack2
+, python, pythonDBus }:
stdenv.mkDerivation rec {
name = "a2jmidid-${version}";
@@ -9,13 +10,16 @@ stdenv.mkDerivation rec {
sha256 = "0pzm0qk5ilqhwz74pydg1jwrds27vm47185dakdrxidb5bv3b5ia";
};
- buildInputs = [ alsaLib dbus jack2 pkgconfig python ];
+ buildInputs = [ makeWrapper pkgconfig alsaLib dbus jack2 python pythonDBus ];
configurePhase = "python waf configure --prefix=$out";
buildPhase = "python waf";
- installPhase = "python waf install";
+ installPhase = ''
+ python waf install
+ wrapProgram $out/bin/a2j_control --set PYTHONPATH $PYTHONPATH
+ '';
meta = with stdenv.lib; {
homepage = http://home.gna.org/a2jmidid;
diff --git a/pkgs/applications/audio/amarok/default.nix b/pkgs/applications/audio/amarok/default.nix
index b1bcfe869f7..6ecdc1f98d4 100644
--- a/pkgs/applications/audio/amarok/default.nix
+++ b/pkgs/applications/audio/amarok/default.nix
@@ -16,8 +16,8 @@ stdenv.mkDerivation rec {
QT_PLUGIN_PATH="${qtscriptgenerator}/lib/qt4/plugins";
- buildInputs = [ qtscriptgenerator stdenv.gcc.libc gettext curl
- libxml2 mysql taglib taglib_extras loudmouth kdelibs automoc4 phonon strigi
+ buildInputs = [ qtscriptgenerator stdenv.cc.libc gettext curl
+ libxml2 mysql.lib taglib taglib_extras loudmouth kdelibs automoc4 phonon strigi
soprano qca2 libmtp liblastfm libgpod pkgconfig qjson ffmpeg libofa nepomuk_core ];
cmakeFlags = "-DKDE4_BUILD_TESTS=OFF";
diff --git a/pkgs/applications/audio/ams-lv2/default.nix b/pkgs/applications/audio/ams-lv2/default.nix
index dd23504d3fa..0001f0a9292 100644
--- a/pkgs/applications/audio/ams-lv2/default.nix
+++ b/pkgs/applications/audio/ams-lv2/default.nix
@@ -1,15 +1,15 @@
-{ stdenv, fetchurl, cairo, gtk, gtkmm, lv2, lvtk, pkgconfig, python }:
+{ stdenv, fetchurl, cairo, fftw, gtk, gtkmm, lv2, lvtk, pkgconfig, python }:
stdenv.mkDerivation rec {
name = "ams-lv2-${version}";
- version = "1.0.2";
+ version = "1.1.0";
src = fetchurl {
url = "https://github.com/blablack/ams-lv2/archive/v${version}.tar.gz";
- sha256 = "0fa1ghf6qahbhj9j1ciyw0hr6nngwksa37hbs651mlz0fn7lz4xm";
+ sha256 = "1kqbl7rc3zrs27c5ga0frw3mlpx15sbxzhf04sfbrd9l60535fd5";
};
- buildInputs = [ cairo gtk gtkmm lv2 lvtk pkgconfig python ];
+ buildInputs = [ cairo fftw gtk gtkmm lv2 lvtk pkgconfig python ];
configurePhase = "python waf configure --prefix=$out";
diff --git a/pkgs/applications/audio/ardour/default.nix b/pkgs/applications/audio/ardour/default.nix
index 62b88cbe077..3142b2c52fc 100644
--- a/pkgs/applications/audio/ardour/default.nix
+++ b/pkgs/applications/audio/ardour/default.nix
@@ -6,7 +6,21 @@
, perl, pkgconfig, python, serd, sord, sratom, suil }:
let
- tag = "3.5.380";
+
+ # Ardour git repo uses a mix of annotated and lightweight tags. Annotated
+ # tags are used for MAJOR.MINOR versioning, and lightweight tags are used
+ # in-between; MAJOR.MINOR.REV where REV is the number of commits since the
+ # last annotated tag. A slightly different version string format is needed
+ # for the 'revision' info that is built into the binary; it is the format of
+ # "git describe" when _not_ on an annotated tag(!): MAJOR.MINOR-REV-HASH.
+
+ # Version to build.
+ tag = "3.5.403";
+
+ # Version info that is built into the binary. Keep in sync with 'tag'. The
+ # last 8 digits is a (fake) commit id.
+ revision = "3.5-403-00000000";
+
in
stdenv.mkDerivation rec {
@@ -15,7 +29,7 @@ stdenv.mkDerivation rec {
src = fetchgit {
url = git://git.ardour.org/ardour/ardour.git;
rev = "refs/tags/${tag}";
- sha256 = "dbcbb2d9143e196d079c27b15266e47d24b81cb7591fe64b717f3485965ded7b";
+ sha256 = "0k1z8sbjf88dqn12kf9cykrqj38vkr879n2g6b4adk6cghn8wz3x";
};
buildInputs =
@@ -27,10 +41,7 @@ stdenv.mkDerivation rec {
];
patchPhase = ''
- # The funny revision number is from `git describe rev`
- printf '#include "libs/ardour/ardour/revision.h"\nnamespace ARDOUR { const char* revision = \"${tag}-g2f6065b\"; }\n' > libs/ardour/revision.cc
- # Note the different version number
- sed -i '33i rev = \"3.5-380-g2f6065b\"' wscript
+ printf '#include "libs/ardour/ardour/revision.h"\nnamespace ARDOUR { const char* revision = \"${revision}\"; }\n' > libs/ardour/revision.cc
sed 's|/usr/include/libintl.h|${glibc}/include/libintl.h|' -i wscript
sed -e 's|^#!/usr/bin/perl.*$|#!${perl}/bin/perl|g' -i tools/fmt-bindings
sed -e 's|^#!/usr/bin/env.*$|#!${perl}/bin/perl|g' -i tools/*.pl
diff --git a/pkgs/applications/audio/ario/default.nix b/pkgs/applications/audio/ario/default.nix
new file mode 100644
index 00000000000..3840d06dd46
--- /dev/null
+++ b/pkgs/applications/audio/ario/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchurl, pkgconfig, gettext, gtk2, expat, intltool, libgcrypt,
+ libunique, gnutls, libxml2, curl, mpd_clientlib, dbus_glib, libnotify,
+ libsoup, avahi, taglib
+ }:
+
+stdenv.mkDerivation rec {
+ version = "1.5.1";
+ name = "ario-${version}";
+
+ src = fetchurl {
+ url = "mirror://sourceforge/ario-player/${name}.tar.gz";
+ sha256 = "07n97618jv1ilxnm5c6qj9zjz0imw3p304mn4hjbjkk3p0d2hc88";
+ };
+
+ patches = [ ./glib-single-include.patch ];
+
+ buildInputs = [
+ pkgconfig gettext gtk2 expat intltool libgcrypt libunique gnutls
+ libxml2 curl mpd_clientlib dbus_glib libnotify libsoup avahi taglib
+ ];
+
+ meta = {
+ description = "GTK2 client for MPD (Music player daemon)";
+ homepage = "http://ario-player.sourceforge.net/";
+ license = stdenv.lib.licenses.gpl2Plus;
+ maintainers = [ stdenv.lib.maintainers.garrison ];
+ platforms = stdenv.lib.platforms.all;
+ };
+}
diff --git a/pkgs/applications/audio/ario/glib-single-include.patch b/pkgs/applications/audio/ario/glib-single-include.patch
new file mode 100644
index 00000000000..45e0a1738f8
--- /dev/null
+++ b/pkgs/applications/audio/ario/glib-single-include.patch
@@ -0,0 +1,40 @@
+From: Michael Biebl
+Origin: vendor
+Bug-Debian: http://bugs.debian.org/665506
+Subject: Including individual glib headers no longer supported
+
+--- a/src/ario-profiles.h
++++ b/src/ario-profiles.h
+@@ -20,7 +20,7 @@
+ #ifndef __ARIO_PROFILES_H
+ #define __ARIO_PROFILES_H
+
+-#include
++#include
+ #include "servers/ario-server.h"
+
+ G_BEGIN_DECLS
+--- a/src/plugins/ario-plugin-info.c
++++ b/src/plugins/ario-plugin-info.c
+@@ -27,7 +27,7 @@
+
+ #include
+ #include
+-#include
++#include
+
+ #include "plugins/ario-plugin-info-priv.h"
+ #include "ario-debug.h"
+--- a/src/ario-util.h
++++ b/src/ario-util.h
+@@ -18,8 +18,8 @@
+ */
+
+ #include "servers/ario-server.h"
+-#include "glib/gslist.h"
+-#include "gdk/gdkpixbuf.h"
++#include
++#include
+
+ /* Number of covers used to generate the drag & drop image */
+ #define MAX_COVERS_IN_DRAG 3
diff --git a/pkgs/applications/audio/audacious/default.nix b/pkgs/applications/audio/audacious/default.nix
index 409a831727b..3ab113c92e8 100644
--- a/pkgs/applications/audio/audacious/default.nix
+++ b/pkgs/applications/audio/audacious/default.nix
@@ -1,28 +1,28 @@
{ stdenv, fetchurl, pkgconfig, glib, gtk3, libmowgli, libmcs
, gettext, dbus_glib, libxml2, libmad, xlibs, alsaLib, libogg
, libvorbis, libcdio, libcddb, flac, ffmpeg, makeWrapper
+, mpg123, neon, faad2
}:
-let
- version = "3.4.3";
-in
+let version = "3.5.2"; in
+
stdenv.mkDerivation {
name = "audacious-${version}";
src = fetchurl {
url = "http://distfiles.audacious-media-player.org/audacious-${version}.tar.bz2";
- sha256 = "04lzwdr1lx6ghbfxzygvnbmdl420w6rm453ds5lyb0hlvzs58d0q";
+ sha256 = "0mhrdj76h0g6q197wgp8rxk6gqsrirrw49hfidcb5b7q5rlvj59r";
};
pluginsSrc = fetchurl {
url = "http://distfiles.audacious-media-player.org/audacious-plugins-${version}.tar.bz2";
- sha256 = "00r88q9fs9a0gicdmk2svcans7igcqgacrw303a5bn44is7pmrmy";
+ sha256 = "1nacd8n46q3pqnwavq3i2ayls609gvxfcp3qqpcsfcdfz3bh15hp";
};
buildInputs =
[ gettext pkgconfig glib gtk3 libmowgli libmcs libxml2 dbus_glib
libmad xlibs.libXcomposite libogg libvorbis flac alsaLib libcdio
- libcddb ffmpeg makeWrapper
+ libcddb ffmpeg makeWrapper mpg123 neon faad2
];
# Here we build bouth audacious and audacious-plugins in one
diff --git a/pkgs/applications/audio/audacity/default.nix b/pkgs/applications/audio/audacity/default.nix
index 7308d84e098..6f25693f734 100644
--- a/pkgs/applications/audio/audacity/default.nix
+++ b/pkgs/applications/audio/audacity/default.nix
@@ -15,7 +15,7 @@ stdenv.mkDerivation rec {
preConfigure = /* we prefer system-wide libs */ ''
mv lib-src lib-src-rm
mkdir lib-src
- mv lib-src-rm/{Makefile*,lib-widget-extra,portaudio-v19,portmixer,portsmf,FileDialog,sbsms} lib-src/
+ mv lib-src-rm/{Makefile*,lib-widget-extra,portaudio-v19,portmixer,portsmf,FileDialog,sbsms,libnyquist} lib-src/
rm -r lib-src-rm/
'';
diff --git a/pkgs/applications/audio/aumix/default.nix b/pkgs/applications/audio/aumix/default.nix
index 41edd51e5f2..f5f0711ecac 100644
--- a/pkgs/applications/audio/aumix/default.nix
+++ b/pkgs/applications/audio/aumix/default.nix
@@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
homepage = http://www.jpj.net/~trevor/aumix.html;
license = stdenv.lib.licenses.gpl2Plus;
- maintainers = [ stdenv.lib.maintainers.ludo ];
+ maintainers = [ ];
platforms = stdenv.lib.platforms.linux;
};
}
diff --git a/pkgs/applications/audio/cantata/default.nix b/pkgs/applications/audio/cantata/default.nix
index 88931520c42..b23384e9293 100644
--- a/pkgs/applications/audio/cantata/default.nix
+++ b/pkgs/applications/audio/cantata/default.nix
@@ -1,6 +1,6 @@
{ stdenv, fetchurl, cmake
-, withQt4 ? true, qt4
-, withQt5 ? false, qt5
+, withQt4 ? false, qt4
+, withQt5 ? true, qt5
# I'm unable to make KDE work here, crashes at runtime so I simply
# make Qt4 the default until someone who wants KDE can figure it out.
@@ -39,7 +39,7 @@ assert withOnlineServices -> withTaglib;
assert withReplaygain -> withTaglib;
let
- version = "1.4.1";
+ version = "1.5.1";
pname = "cantata";
fstat = x: fn: "-DENABLE_" + fn + "=" + (if x then "ON" else "OFF");
fstats = x: map (fstat x);
@@ -50,14 +50,14 @@ stdenv.mkDerivation rec {
src = fetchurl {
inherit name;
- url = "https://drive.google.com/uc?export=download&id=0Bzghs6gQWi60eXhuZ1Z3bGM2bjQ";
- sha256 = "b0d5a1798efd275d72dffb87bc0f016fc865dbd1384b7c9af039cebdffe0cca3";
+ url = "https://drive.google.com/uc?export=download&id=0Bzghs6gQWi60UktwaTRMTjRIUW8";
+ sha256 = "0y7y3nbiqgh1ghb47n4lfyp163wvazvhavlshb1c18ik03fkn5sp";
};
buildInputs =
[ cmake ]
++ stdenv.lib.optional withQt4 qt4
- ++ stdenv.lib.optional withQt5 qt5
+ ++ stdenv.lib.optionals withQt5 (with qt5; [ base svg tools ])
++ stdenv.lib.optional withKDE4 kde4.kdelibs
++ stdenv.lib.optionals withTaglib [ taglib taglib_extras ]
++ stdenv.lib.optionals withReplaygain [ ffmpeg speex mpg123 ]
@@ -92,8 +92,8 @@ stdenv.mkDerivation rec {
];
meta = with stdenv.lib; {
- homepage = "http://code.google.com/p/cantata/";
- description = "A graphical client for MPD.";
+ homepage = http://code.google.com/p/cantata/;
+ description = "A graphical client for MPD";
license = licenses.gpl3;
# Technically Cantata can run on Windows so if someone wants to
diff --git a/pkgs/applications/audio/caudec/default.nix b/pkgs/applications/audio/caudec/default.nix
new file mode 100644
index 00000000000..24613d4dd96
--- /dev/null
+++ b/pkgs/applications/audio/caudec/default.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchurl, makeWrapper, bash, bc, findutils, flac, lame, opusTools, procps, sox }:
+
+let
+ version = "1.7.5";
+in
+
+stdenv.mkDerivation rec {
+ name = "caudec-${version}";
+
+ src = fetchurl {
+ url = "http://caudec.net/downloads/caudec-${version}.tar.gz";
+ sha256 = "5d1f5ab3286bb748bd29cbf45df2ad2faf5ed86070f90deccf71c60be832f3d5";
+ };
+
+ preBuild = ''
+ patchShebangs ./install.sh
+ '';
+
+ buildInputs = [ bash makeWrapper ];
+
+ installPhase = ''
+ ./install.sh --prefix=$out/bin
+ '';
+
+ postFixup = ''
+ for executable in $(cd $out/bin && ls); do
+ wrapProgram $out/bin/$executable \
+ --prefix PATH : "${bc}/bin:${findutils}/bin:${sox}/bin:${procps}/bin:${opusTools}/bin:${lame}/bin:${flac}/bin"
+ done
+ '';
+
+ meta = with stdenv.lib; {
+ homepage = http://caudec.net/;
+ description = "A multiprocess audio converter that supports many formats (FLAC, MP3, Ogg Vorbis, Windows codecs and many more)";
+ license = licenses.gpl3;
+ platforms = platforms.linux ++ platforms.darwin;
+ maintainers = with maintainers; [ _1126 ];
+ };
+}
diff --git a/pkgs/applications/audio/cava/default.nix b/pkgs/applications/audio/cava/default.nix
new file mode 100644
index 00000000000..c1b5aef333b
--- /dev/null
+++ b/pkgs/applications/audio/cava/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchgit, alsaLib, fftw }:
+
+stdenv.mkDerivation rec {
+ name = "cava-${version}";
+ version = "27dbdf47daae44c780db9998c760007b3bf63738";
+
+ buildInputs = [ alsaLib fftw ];
+
+ src = fetchgit {
+ url = "https://github.com/karlstav/cava";
+ rev = version;
+ sha256 = "1a61e2c869376276cf78e6446cd1cc7f96b3e378fa8bc0bc4c5ca81945429909";
+ };
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp cava $out/bin
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Console-based Audio Visualizer for Alsa";
+ homepage = https://github.com/karlstav/cava;
+ maintainers = with maintainers; [offline];
+ platforms = with platforms; linux;
+ };
+}
diff --git a/pkgs/applications/audio/cdparanoia/default.nix b/pkgs/applications/audio/cdparanoia/default.nix
index 6bd9e0b376e..5c5416b79e1 100644
--- a/pkgs/applications/audio/cdparanoia/default.nix
+++ b/pkgs/applications/audio/cdparanoia/default.nix
@@ -7,6 +7,8 @@ stdenv.mkDerivation rec {
url = "http://downloads.xiph.org/releases/cdparanoia/${name}.src.tgz";
sha256 = "1pv4zrajm46za0f6lv162iqffih57a8ly4pc69f7y0gfyigb8p80";
};
+
+ preConfigure = "unset CC";
meta = {
homepage = http://xiph.org/paranoia;
diff --git a/pkgs/applications/audio/chuck/darwin-limits.patch b/pkgs/applications/audio/chuck/darwin-limits.patch
new file mode 100644
index 00000000000..3387f725544
--- /dev/null
+++ b/pkgs/applications/audio/chuck/darwin-limits.patch
@@ -0,0 +1,13 @@
+--- a/src/util_string.cpp 2014-10-27 22:52:11.875981552 +0100
++++ b/src/util_string.cpp 2014-10-27 22:54:18.613001994 +0100
+@@ -40,6 +40,10 @@
+ #include
+ #endif // __PLATFORM_LINUX__
+
++#ifdef __PLATFORM_MACOSX__
++#include
++#endif // __PLATFORM_MACOSX__
++
+ #include
+ using namespace std;
+
diff --git a/pkgs/applications/audio/chuck/default.nix b/pkgs/applications/audio/chuck/default.nix
new file mode 100644
index 00000000000..7725ba1e4c8
--- /dev/null
+++ b/pkgs/applications/audio/chuck/default.nix
@@ -0,0 +1,38 @@
+{ stdenv, fetchurl, alsaLib, bison, flex, libsndfile, which }:
+
+stdenv.mkDerivation rec {
+ version = "1.3.4.0";
+ name = "chuck-${version}";
+
+ src = fetchurl {
+ url = "http://chuck.cs.princeton.edu/release/files/chuck-${version}.tgz";
+ sha256 = "0cwbk8b1i18nkh2nxwzk2prranw83lgglxw7ccnp6b0r2b2yfpmn";
+ };
+
+ buildInputs = [ bison flex libsndfile which ]
+ ++ stdenv.lib.optional (!stdenv.isDarwin) alsaLib;
+
+ patches = [ ./darwin-limits.patch ];
+
+ postPatch = ''
+ substituteInPlace src/makefile --replace "/usr/bin" "$out/bin"
+ substituteInPlace src/makefile.osx --replace "xcodebuild" "/usr/bin/xcodebuild"
+ substituteInPlace src/makefile.osx --replace "weak_framework" "framework"
+ '';
+
+ buildPhase =
+ stdenv.lib.optionals stdenv.isLinux ["make -C src linux-alsa"] ++
+ stdenv.lib.optionals stdenv.isDarwin ["make -C src osx"];
+
+ installPhase = ''
+ install -Dm755 ./src/chuck $out/bin/chuck
+ '';
+
+ meta = {
+ description = "Programming language for real-time sound synthesis and music creation";
+ homepage = http://chuck.cs.princeton.edu;
+ license = stdenv.lib.licenses.gpl2;
+ platforms = with stdenv.lib.platforms; linux ++ darwin;
+ maintainers = with stdenv.lib.maintainers; [ ftrvxmtrx ];
+ };
+}
diff --git a/pkgs/applications/audio/clementine/clementine-dbus-namespace.patch b/pkgs/applications/audio/clementine/clementine-dbus-namespace.patch
new file mode 100644
index 00000000000..2240debd0e4
--- /dev/null
+++ b/pkgs/applications/audio/clementine/clementine-dbus-namespace.patch
@@ -0,0 +1,36 @@
+From ec580cb815c16ec1ab43a469d5af7d51d8d03082 Mon Sep 17 00:00:00 2001
+From: Chocobozzz
+Date: Wed, 16 Jul 2014 15:57:25 +0200
+Subject: [PATCH] No namespaces for DBus interfaces. Fixes #4401
+
+---
+ src/CMakeLists.txt | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index 650fa74..775b0a5 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -892,11 +892,6 @@ optional_source(LINUX SOURCES widgets/osd_x11.cpp)
+ if(HAVE_DBUS)
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dbus)
+
+- # Hack to get it to generate interfaces without namespaces - required
+- # because otherwise org::freedesktop::UDisks and
+- # org::freedesktop::UDisks::Device conflict.
+- list(APPEND QT_DBUSXML2CPP_EXECUTABLE -N)
+-
+ # MPRIS DBUS interfaces
+ qt4_add_dbus_adaptor(SOURCES
+ dbus/org.freedesktop.MediaPlayer.player.xml
+@@ -964,6 +959,10 @@ if(HAVE_DBUS)
+
+ # DeviceKit DBUS interfaces
+ if(HAVE_DEVICEKIT)
++ set_source_files_properties(dbus/org.freedesktop.UDisks.xml
++ PROPERTIES NO_NAMESPACE dbus/udisks)
++ set_source_files_properties(dbus/org.freedesktop.UDisks.Device.xml
++ PROPERTIES NO_NAMESPACE dbus/udisksdevice)
+ qt4_add_dbus_interface(SOURCES
+ dbus/org.freedesktop.UDisks.xml
+ dbus/udisks)
diff --git a/pkgs/applications/audio/clementine/default.nix b/pkgs/applications/audio/clementine/default.nix
index 604c35f46ce..538f54fbaf8 100644
--- a/pkgs/applications/audio/clementine/default.nix
+++ b/pkgs/applications/audio/clementine/default.nix
@@ -1,7 +1,8 @@
{ stdenv, fetchurl, boost, cmake, gettext, gstreamer, gst_plugins_base
+, gst_plugins_good, gst_plugins_bad, gst_plugins_ugly, gst_ffmpeg
, liblastfm, qt4, taglib, fftw, glew, qjson, sqlite, libgpod, libplist
, usbmuxd, libmtp, gvfs, libcdio, protobuf, libspotify, qca2, pkgconfig
-, sparsehash, config }:
+, sparsehash, config, makeWrapper }:
let withSpotify = config.clementine.spotify or false;
in
@@ -13,7 +14,11 @@ stdenv.mkDerivation {
sha256 = "1gx1109i4pylz6x7gvp4rdzc6dvh0w6in6hfbygw01d08l26bxbx";
};
- patches = [ ./clementine-1.2.1-include-paths.patch ];
+ patches =
+ [
+ ./clementine-1.2.1-include-paths.patch
+ ./clementine-dbus-namespace.patch
+ ];
buildInputs = [
boost
@@ -22,6 +27,9 @@ stdenv.mkDerivation {
gettext
glew
gst_plugins_base
+ gst_plugins_good
+ gst_plugins_ugly
+ gst_ffmpeg
gstreamer
gvfs
libcdio
@@ -29,6 +37,7 @@ stdenv.mkDerivation {
liblastfm
libmtp
libplist
+ makeWrapper
pkgconfig
protobuf
qca2
@@ -42,6 +51,11 @@ stdenv.mkDerivation {
enableParallelBuilding = true;
+ postInstall = ''
+ wrapProgram $out/bin/clementine \
+ --set GST_PLUGIN_SYSTEM_PATH "$GST_PLUGIN_SYSTEM_PATH"
+ '';
+
meta = with stdenv.lib; {
homepage = "http://www.clementine-player.org";
description = "A multiplatform music player";
diff --git a/pkgs/applications/audio/cmus/default.nix b/pkgs/applications/audio/cmus/default.nix
index 4f9c491a3a5..fd252754d66 100644
--- a/pkgs/applications/audio/cmus/default.nix
+++ b/pkgs/applications/audio/cmus/default.nix
@@ -1,21 +1,22 @@
-{ stdenv, fetchurl, ncurses, pkgconfig, alsaLib, flac, libmad, ffmpeg, libvorbis, mpc, mp4v2 }:
+{ stdenv, fetchgit, ncurses, pkgconfig, alsaLib, flac, libmad, ffmpeg, libvorbis, libmpc, mp4v2, libcue, pulseaudio}:
stdenv.mkDerivation rec {
name = "cmus-${version}";
- version = "2.5.0";
+ version = "2.6.0";
- src = fetchurl {
- url = "mirror://sourceforge/cmus/cmus-v${version}.tar.bz2";
- sha256 = "1pwd3jifv12yr0yr77hsv5c9y8ay6kn2b5a3s5i8v2c882vgl890";
+ src = fetchgit {
+ url = https://github.com/cmus/cmus.git;
+ rev = "46b71032da827d22d4fae5bf2afcc4c9afef568c";
+ sha256 = "1hkqifll5ryf3ljp3w1dxz1p8m6rk34fpazc6vwavis6ga310hka";
};
configurePhase = "./configure prefix=$out";
- buildInputs = [ ncurses pkgconfig alsaLib flac libmad ffmpeg libvorbis mpc mp4v2 ];
+ buildInputs = [ ncurses pkgconfig alsaLib flac libmad ffmpeg libvorbis libmpc mp4v2 libcue pulseaudio ];
meta = {
description = "Small, fast and powerful console music player for Linux and *BSD";
- homepage = http://cmus.sourceforge.net;
+ homepage = https://cmus.github.io/;
license = stdenv.lib.licenses.gpl2;
};
}
diff --git a/pkgs/applications/audio/csound/default.nix b/pkgs/applications/audio/csound/default.nix
index 19c590330f6..64f3f3586a3 100644
--- a/pkgs/applications/audio/csound/default.nix
+++ b/pkgs/applications/audio/csound/default.nix
@@ -12,13 +12,13 @@
}:
stdenv.mkDerivation {
- name = "csound-5.19.01";
+ name = "csound-6.03.2";
enableParallelBuilding = true;
src = fetchurl {
- url = mirror://sourceforge/csound/Csound5.19.01.tar.gz;
- sha256 = "078i69jwgadmxwa5ffn8h1py7cmd9asa8swnh38fyp56lzgzn669";
+ url = mirror://sourceforge/csound/Csound6.03.2.tar.gz;
+ sha256 = "0w6ij57dbfjljpf05bb9r91jphwaq1v63rh0713vl2n11d73dy7m";
};
buildInputs = [ cmake libsndfile flex bison alsaLib pulseaudio tcltk ];
diff --git a/pkgs/applications/audio/deadbeef/default.nix b/pkgs/applications/audio/deadbeef/default.nix
new file mode 100644
index 00000000000..ca8ce453e63
--- /dev/null
+++ b/pkgs/applications/audio/deadbeef/default.nix
@@ -0,0 +1,98 @@
+{ stdenv, fetchurl, intltool, pkgconfig
+# deadbeef can use either gtk2 or gtk3
+, gtk2Support ? true, gtk2 ? null
+, gtk3Support ? false, gtk3 ? null, gsettings_desktop_schemas ? null, makeWrapper ? null
+# input plugins
+, vorbisSupport ? true, libvorbis ? null
+, mp123Support ? true, libmad ? null
+, flacSupport ? true, flac ? null
+, wavSupport ? true, libsndfile ? null
+, cdaSupport ? true, libcdio ? null, libcddb ? null
+, aacSupport ? true, faad2 ? null
+, wavpackSupport ? false, wavpack ? null
+, ffmpegSupport ? false, ffmpeg ? null
+# misc plugins
+, zipSupport ? true, libzip ? null
+, artworkSupport ? true, imlib2 ? null
+, hotkeysSupport ? true, libX11 ? null
+, osdSupport ? true, dbus ? null
+# output plugins
+, alsaSupport ? true, alsaLib ? null
+, pulseSupport ? true, pulseaudio ? null
+# effect plugins
+, resamplerSupport ? true, libsamplerate ? null
+, overloadSupport ? true, zlib ? null
+# transports
+, remoteSupport ? true, curl ? null
+}:
+
+assert gtk2Support || gtk3Support;
+assert gtk2Support -> gtk2 != null;
+assert gtk3Support -> gtk3 != null && gsettings_desktop_schemas != null && makeWrapper != null;
+assert vorbisSupport -> libvorbis != null;
+assert mp123Support -> libmad != null;
+assert flacSupport -> flac != null;
+assert wavSupport -> libsndfile != null;
+assert cdaSupport -> (libcdio != null && libcddb != null);
+assert aacSupport -> faad2 != null;
+assert zipSupport -> libzip != null;
+assert ffmpegSupport -> ffmpeg != null;
+assert artworkSupport -> imlib2 != null;
+assert hotkeysSupport -> libX11 != null;
+assert osdSupport -> dbus != null;
+assert alsaSupport -> alsaLib != null;
+assert pulseSupport -> pulseaudio != null;
+assert resamplerSupport -> libsamplerate != null;
+assert overloadSupport -> zlib != null;
+assert wavpackSupport -> wavpack != null;
+assert remoteSupport -> curl != null;
+
+stdenv.mkDerivation rec {
+ name = "deadbeef-0.6.2";
+
+ src = fetchurl {
+ url = "http://garr.dl.sourceforge.net/project/deadbeef/${name}.tar.bz2";
+ sha256 = "06jfsqyakpvq0xhah7dlyvdzh5ym3hhb4yfczczw11ijd1kbjcrl";
+ };
+
+ buildInputs = with stdenv.lib;
+ optional gtk2Support gtk2
+ ++ optionals gtk3Support [gtk3 gsettings_desktop_schemas]
+ ++ optional vorbisSupport libvorbis
+ ++ optional mp123Support libmad
+ ++ optional flacSupport flac
+ ++ optional wavSupport libsndfile
+ ++ optionals cdaSupport [libcdio libcddb]
+ ++ optional aacSupport faad2
+ ++ optional zipSupport libzip
+ ++ optional ffmpegSupport ffmpeg
+ ++ optional artworkSupport imlib2
+ ++ optional hotkeysSupport libX11
+ ++ optional osdSupport dbus
+ ++ optional alsaSupport alsaLib
+ ++ optional pulseSupport pulseaudio
+ ++ optional resamplerSupport libsamplerate
+ ++ optional overloadSupport zlib
+ ++ optional wavpackSupport wavpack
+ ++ optional remoteSupport curl
+ ;
+
+ nativeBuildInputs = with stdenv.lib; [ intltool pkgconfig ]
+ ++ optional gtk3Support makeWrapper;
+
+ enableParallelBuilding = true;
+
+ postInstall = if !gtk3Support then "" else ''
+ wrapProgram "$out/bin/deadbeef" \
+ --prefix XDG_DATA_DIRS : "$GSETTINGS_SCHEMAS_PATH"
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Ultimate Music Player for GNU/Linux";
+ homepage = http://deadbeef.sourceforge.net/;
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ maintainers = [ maintainers.abbradar ];
+ repositories.git = https://github.com/Alexey-Yakovenko/deadbeef;
+ };
+}
diff --git a/pkgs/applications/audio/distrho/default.nix b/pkgs/applications/audio/distrho/default.nix
index aa3a76c3af1..a8c710f2099 100644
--- a/pkgs/applications/audio/distrho/default.nix
+++ b/pkgs/applications/audio/distrho/default.nix
@@ -1,16 +1,13 @@
{ stdenv, fetchgit, alsaLib, fftwSinglePrec, freetype, jack2
, libxslt, lv2, pkgconfig, premake3, xlibs }:
-let
- rev = "99efbf0b";
-in
stdenv.mkDerivation rec {
- name = "distrho-${rev}";
+ name = "distrho-ports-git-2015-01-28";
src = fetchgit {
- url = "https://github.com/falkTX/DISTRHO.git";
- inherit rev;
- sha256 = "ed26a6edca19ebb8260b3dc042f69c32162e1d91179fb9d22da42ec7131936f9";
+ url = "https://github.com/DISTRHO/DISTRHO-Ports.git";
+ rev = "b4e2dc24802fe6804c60fcd2559a0bca46b7709c";
+ sha256 = "661ff6f7cda71a8dd08cbcea3f560e99f0fc2232053cbc9a2aaba854137805c6";
};
patchPhase = ''
@@ -50,5 +47,9 @@ stdenv.mkDerivation rec {
'';
maintainers = [ maintainers.goibhniu ];
platforms = platforms.linux;
+
+ # The old repo was removed and split into multiple repos. More
+ # work is required to get everything to build and work.
+ broken = true;
};
}
diff --git a/pkgs/applications/audio/drumgizmo/default.nix b/pkgs/applications/audio/drumgizmo/default.nix
new file mode 100644
index 00000000000..2daafda554e
--- /dev/null
+++ b/pkgs/applications/audio/drumgizmo/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, fetchurl, alsaLib, expat, glib, jack2, libX11, libpng
+, libpthreadstubs, libsmf, libsndfile, lv2, pkgconfig
+}:
+
+stdenv.mkDerivation rec {
+ version = "0.9.6";
+ name = "drumgizmo-${version}";
+
+ src = fetchurl {
+ url = "http://www.drumgizmo.org/releases/${name}/${name}.tar.gz";
+ sha256 = "1qs8aa1v8cw5zgfzcnr2dc4w0y5yzsgrywlnx2hfvx2si3as0mw4";
+ };
+
+ configureFlags = [ "--enable-lv2" ];
+
+ buildInputs = [
+ alsaLib expat glib jack2 libX11 libpng libpthreadstubs libsmf
+ libsndfile lv2 pkgconfig
+ ];
+
+ meta = with stdenv.lib; {
+ description = "An LV2 sample based drum plugin";
+ homepage = http://www.drumgizmo.org;
+ license = licenses.gpl3;
+ platforms = platforms.linux;
+ maintainers = [ maintainers.goibhniu ];
+ };
+}
diff --git a/pkgs/applications/audio/drumkv1/default.nix b/pkgs/applications/audio/drumkv1/default.nix
index 775cf5ca606..e27b95c81e5 100644
--- a/pkgs/applications/audio/drumkv1/default.nix
+++ b/pkgs/applications/audio/drumkv1/default.nix
@@ -2,11 +2,11 @@
stdenv.mkDerivation rec {
name = "drumkv1-${version}";
- version = "0.5.0";
+ version = "0.6.0";
src = fetchurl {
url = "mirror://sourceforge/drumkv1/${name}.tar.gz";
- sha256 = "16bjkp22hfpmzj5di98dddzslavgvhw5z7pgjzmjqz9dxvbqwq1k";
+ sha256 = "1y3imsh059y9sihr92f3drwmcby4x3krmhly111ahwkydb94kphw";
};
buildInputs = [ jack2 libsndfile lv2 qt4 ];
diff --git a/pkgs/applications/audio/easytag/default.nix b/pkgs/applications/audio/easytag/default.nix
index c421dcc60cb..2d738f55c28 100644
--- a/pkgs/applications/audio/easytag/default.nix
+++ b/pkgs/applications/audio/easytag/default.nix
@@ -1,32 +1,35 @@
-{ stdenv, fetchurl, pkgconfig, intltool, gtk, glib, libid3tag, id3lib, taglib
-, libvorbis, libogg, flac
+{ stdenv, fetchurl, pkgconfig, intltool, gtk3, glib, libid3tag, id3lib, taglib
+, libvorbis, libogg, flac, itstool, libxml2, gsettings_desktop_schemas
+, makeWrapper, gnome_icon_theme, dconf
}:
stdenv.mkDerivation rec {
name = "easytag-${version}";
- version = "2.1.8";
+ version = "2.3.2";
src = fetchurl {
- url = "mirror://gnome/sources/easytag/2.1/${name}.tar.xz";
- sha256 = "1ab5iv0a83cdf07qzi81ydfk5apay06nxags9m07msqalz4pabqs";
+ url = "mirror://gnome/sources/easytag/2.3/${name}.tar.xz";
+ sha256 = "0bj3sj4yzlnhan38j84acs7qv27fl3xy4rdrfq6dnpz4q6qccm84";
};
- preConfigure = ''
- # pkg-config v0.23 should be enough.
- sed -i -e '/_pkg_min_version=0.24/s/24/23/' \
- -e 's/have_mp3=no/have_mp3=yes/' \
- -e 's/ID3TAG_DEPS="id3tag"/ID3TAG_DEPS=""/' configure
+ preFixup = ''
+ wrapProgram $out/bin/easytag \
+ --prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH:$out/share" \
+ --prefix GIO_EXTRA_MODULES : "${dconf}/lib/gio/modules"
'';
NIX_LDFLAGS = "-lid3tag -lz";
+ nativeBuildInputs = [ makeWrapper ];
buildInputs = [
- pkgconfig intltool gtk glib libid3tag id3lib taglib libvorbis libogg flac
+ pkgconfig intltool gtk3 glib libid3tag id3lib taglib libvorbis libogg flac
+ itstool libxml2 gsettings_desktop_schemas gnome_icon_theme dconf
];
meta = {
description = "View and edit tags for various audio files";
homepage = "http://projects.gnome.org/easytag/";
license = stdenv.lib.licenses.gpl2Plus;
+ maintainers = with stdenv.lib.maintainers; [ fuuzetsu ];
};
}
diff --git a/pkgs/applications/audio/faust/default.nix b/pkgs/applications/audio/faust/default.nix
new file mode 100644
index 00000000000..722c762b7b4
--- /dev/null
+++ b/pkgs/applications/audio/faust/default.nix
@@ -0,0 +1,209 @@
+{ stdenv
+, coreutils
+, fetchgit
+, makeWrapper
+, pkgconfig
+}:
+
+with stdenv.lib.strings;
+
+let
+
+ version = "8-1-2015";
+
+ src = fetchgit {
+ url = git://git.code.sf.net/p/faudiostream/code;
+ rev = "4db76fdc02b6aec8d15a5af77fcd5283abe963ce";
+ sha256 = "f1ac92092ee173e4bcf6b2cb1ac385a7c390fb362a578a403b2b6edd5dc7d5d0";
+ };
+
+ meta = with stdenv.lib; {
+ homepage = http://faust.grame.fr/;
+ downloadPage = http://sourceforge.net/projects/faudiostream/files/;
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ magnetophon pmahoney ];
+ };
+
+ faust = stdenv.mkDerivation {
+
+ name = "faust-${version}";
+
+ inherit src;
+
+ buildInputs = [ makeWrapper ];
+
+ passthru = {
+ inherit wrap wrapWithBuildEnv;
+ };
+
+ preConfigure = ''
+ makeFlags="$makeFlags prefix=$out"
+
+ # The faust makefiles use 'system ?= $(shell uname -s)' but nix
+ # defines 'system' env var, so undefine that so faust detects the
+ # correct system.
+ unset system
+ '';
+
+ # Remove most faust2appl scripts since they won't run properly
+ # without additional paths setup. See faust.wrap,
+ # faust.wrapWithBuildEnv.
+ postInstall = ''
+ # syntax error when eval'd directly
+ pattern="faust2!(svg)"
+ (shopt -s extglob; rm "$out"/bin/$pattern)
+ '';
+
+ postFixup = ''
+ # Set faustpath explicitly.
+ substituteInPlace "$out"/bin/faustpath \
+ --replace "/usr/local /usr /opt /opt/local" "$out"
+
+ # The 'faustoptflags' is 'source'd into other faust scripts and
+ # not used as an executable, so patch 'uname' usage directly
+ # rather than use makeWrapper.
+ substituteInPlace "$out"/bin/faustoptflags \
+ --replace uname "${coreutils}/bin/uname"
+
+ # wrapper for scripts that don't need faust.wrap*
+ for script in "$out"/bin/faust2*; do
+ wrapProgram "$script" \
+ --prefix PATH : "$out"/bin
+ done
+ '';
+
+ meta = meta // {
+ description = "A functional programming language for realtime audio signal processing";
+ longDescription = ''
+ FAUST (Functional Audio Stream) is a functional programming
+ language specifically designed for real-time signal processing
+ and synthesis. FAUST targets high-performance signal processing
+ applications and audio plug-ins for a variety of platforms and
+ standards.
+ The Faust compiler translates DSP specifications into very
+ efficient C++ code. Thanks to the notion of architecture,
+ FAUST programs can be easily deployed on a large variety of
+ audio platforms and plugin formats (jack, alsa, ladspa, maxmsp,
+ puredata, csound, supercollider, pure, vst, coreaudio) without
+ any change to the FAUST code.
+
+ This package has just the compiler, libraries, and headers.
+ Install faust2* for specific faust2appl scripts.
+ '';
+ };
+
+ };
+
+ # Default values for faust2appl.
+ faust2ApplBase =
+ { baseName
+ , dir ? "tools/faust2appls"
+ , scripts ? [ baseName ]
+ , ...
+ }@args:
+
+ args // {
+ name = "${baseName}-${version}";
+
+ inherit src;
+
+ configurePhase = ":";
+
+ buildPhase = ":";
+
+ installPhase = ''
+ runHook preInstall
+
+ mkdir -p "$out/bin"
+ for script in ${concatStringsSep " " scripts}; do
+ cp "${dir}/$script" "$out/bin/"
+ done
+
+ runHook postInstall
+ '';
+
+ postInstall = ''
+ # For the faust2appl script, change 'faustpath' and
+ # 'faustoptflags' to absolute paths.
+ for script in "$out"/bin/*; do
+ substituteInPlace "$script" \
+ --replace ". faustpath" ". '${faust}/bin/faustpath'" \
+ --replace ". faustoptflags" ". '${faust}/bin/faustoptflags'"
+ done
+ '';
+
+ meta = meta // {
+ description = "The ${baseName} script, part of faust functional programming language for realtime audio signal processing";
+ };
+ };
+
+ # Some 'faust2appl' scripts, such as faust2alsa, run faust to
+ # generate cpp code, then invoke the c++ compiler to build the code.
+ # This builder wraps these scripts in parts of the stdenv such that
+ # when the scripts are called outside any nix build, they behave as
+ # if they were running inside a nix build in terms of compilers and
+ # paths being configured (e.g. rpath is set so that compiled
+ # binaries link to the libs inside the nix store)
+ #
+ # The function takes two main args: the appl name (e.g.
+ # 'faust2alsa') and an optional list of propagatedBuildInputs. It
+ # returns a derivation that contains only the bin/${appl} script,
+ # wrapped up so that it will run as if it was inside a nix build
+ # with those build inputs.
+ #
+ # The build input 'faust' is automatically added to the
+ # propagatedBuildInputs.
+ wrapWithBuildEnv =
+ { baseName
+ , propagatedBuildInputs ? [ ]
+ , ...
+ }@args:
+
+ stdenv.mkDerivation ((faust2ApplBase args) // {
+
+ buildInputs = [ makeWrapper pkgconfig ];
+
+ propagatedBuildInputs = [ faust ] ++ propagatedBuildInputs;
+
+ postFixup = ''
+
+ # export parts of the build environment
+ for script in "$out"/bin/*; do
+ wrapProgram "$script" \
+ --set FAUST_LIB_PATH "${faust}/lib/faust" \
+ --prefix PATH : "$PATH" \
+ --prefix PKG_CONFIG_PATH : "$PKG_CONFIG_PATH" \
+ --set NIX_CFLAGS_COMPILE "\"$NIX_CFLAGS_COMPILE\"" \
+ --set NIX_LDFLAGS "\"$NIX_LDFLAGS\""
+ done
+ '';
+ });
+
+ # Builder for 'faust2appl' scripts, such as faust2firefox that
+ # simply need to be wrapped with some dependencies on PATH.
+ #
+ # The build input 'faust' is automatically added to the PATH.
+ wrap =
+ { baseName
+ , runtimeInputs ? [ ]
+ , ...
+ }@args:
+
+ let
+
+ runtimePath = concatStringsSep ":" (map (p: "${p}/bin") ([ faust ] ++ runtimeInputs));
+
+ in stdenv.mkDerivation ((faust2ApplBase args) // {
+
+ buildInputs = [ makeWrapper ];
+
+ postFixup = ''
+ for script in "$out"/bin/*; do
+ wrapProgram "$script" --prefix PATH : "${runtimePath}"
+ done
+ '';
+
+ });
+
+in faust
diff --git a/pkgs/applications/audio/faust/faust2alqt.nix b/pkgs/applications/audio/faust/faust2alqt.nix
new file mode 100644
index 00000000000..8ac26e488b3
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2alqt.nix
@@ -0,0 +1,15 @@
+{ faust
+, alsaLib
+, qt4
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2alqt";
+
+ propagatedBuildInputs = [
+ alsaLib
+ qt4
+ ];
+
+}
diff --git a/pkgs/applications/audio/faust/faust2alsa.nix b/pkgs/applications/audio/faust/faust2alsa.nix
new file mode 100644
index 00000000000..2fe03d73a23
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2alsa.nix
@@ -0,0 +1,29 @@
+{ faust
+, alsaLib
+, atk
+, cairo
+, fontconfig
+, freetype
+, gdk_pixbuf
+, glib
+, gtk
+, pango
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2alsa";
+
+ propagatedBuildInputs = [
+ alsaLib
+ atk
+ cairo
+ fontconfig
+ freetype
+ gdk_pixbuf
+ glib
+ gtk
+ pango
+ ];
+
+}
diff --git a/pkgs/applications/audio/faust/faust2csound.nix b/pkgs/applications/audio/faust/faust2csound.nix
new file mode 100644
index 00000000000..eb5e5831cdd
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2csound.nix
@@ -0,0 +1,20 @@
+{ faust
+, csound
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2csound";
+
+ propagatedBuildInputs = [
+ csound
+ ];
+
+ # faust2csound generated .cpp files have
+ # #include "csdl.h"
+ # but that file is in the csound/ subdirectory
+ preFixup = ''
+ NIX_CFLAGS_COMPILE="$(printf '%s' "$NIX_CFLAGS_COMPILE" | sed 's%${csound}/include%${csound}/include/csound%')"
+ '';
+
+}
diff --git a/pkgs/applications/audio/faust/faust2firefox.nix b/pkgs/applications/audio/faust/faust2firefox.nix
new file mode 100644
index 00000000000..b2cc6f46457
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2firefox.nix
@@ -0,0 +1,14 @@
+{ faust
+, xdg_utils
+}:
+
+# This just runs faust2svg, then attempts to open a browser using
+# 'xdg-open'.
+
+faust.wrap {
+
+ baseName = "faust2firefox";
+
+ runtimeInputs = [ xdg_utils ];
+
+}
diff --git a/pkgs/applications/audio/faust/faust2jack.nix b/pkgs/applications/audio/faust/faust2jack.nix
new file mode 100644
index 00000000000..bec523ad021
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2jack.nix
@@ -0,0 +1,23 @@
+{ faust
+, gtk
+, jack2
+, opencv
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2jack";
+
+ scripts = [
+ "faust2jack"
+ "faust2jackinternal"
+ "faust2jackconsole"
+ ];
+
+ propagatedBuildInputs = [
+ gtk
+ jack2
+ opencv
+ ];
+
+}
diff --git a/pkgs/applications/audio/faust/faust2jaqt.nix b/pkgs/applications/audio/faust/faust2jaqt.nix
new file mode 100644
index 00000000000..3590bc6860d
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2jaqt.nix
@@ -0,0 +1,22 @@
+{ faust
+, jack2
+, opencv
+, qt4
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2jaqt";
+
+ scripts = [
+ "faust2jaqt"
+ "faust2jackserver"
+ ];
+
+ propagatedBuildInputs = [
+ jack2
+ opencv
+ qt4
+ ];
+
+}
diff --git a/pkgs/applications/audio/faust/faust2lv2.nix b/pkgs/applications/audio/faust/faust2lv2.nix
new file mode 100644
index 00000000000..4d11395e738
--- /dev/null
+++ b/pkgs/applications/audio/faust/faust2lv2.nix
@@ -0,0 +1,11 @@
+{ faust
+, lv2
+}:
+
+faust.wrapWithBuildEnv {
+
+ baseName = "faust2lv2";
+
+ propagatedBuildInputs = [ lv2 ];
+
+}
diff --git a/pkgs/applications/audio/flac/default.nix b/pkgs/applications/audio/flac/default.nix
index 0256eacc436..80e4e49fb18 100644
--- a/pkgs/applications/audio/flac/default.nix
+++ b/pkgs/applications/audio/flac/default.nix
@@ -1,11 +1,11 @@
{ stdenv, fetchurl, libogg }:
stdenv.mkDerivation rec {
- name = "flac-1.3.0";
+ name = "flac-1.3.1";
src = fetchurl {
url = "http://downloads.xiph.org/releases/flac/${name}.tar.xz";
- sha256 = "1p0hh190kqvpkbk1bbajd81jfbmkyl4fn2i7pggk2zppq6m68bgs";
+ sha256 = "4773c0099dba767d963fd92143263be338c48702172e8754b9bc5103efe1c56c";
};
buildInputs = [ libogg ];
@@ -18,6 +18,6 @@ stdenv.mkDerivation rec {
homepage = http://xiph.org/flac/;
description = "Library and tools for encoding and decoding the FLAC lossless audio file format";
platforms = platforms.all;
- maintainers = maintainers.mornfall;
+ maintainers = [ maintainers.mornfall ];
};
}
diff --git a/pkgs/applications/audio/fldigi/default.nix b/pkgs/applications/audio/fldigi/default.nix
index e78095a9c5d..5a4793a09c1 100644
--- a/pkgs/applications/audio/fldigi/default.nix
+++ b/pkgs/applications/audio/fldigi/default.nix
@@ -2,13 +2,13 @@
libsamplerate, pulseaudio, libXinerama, gettext, pkgconfig, alsaLib }:
stdenv.mkDerivation rec {
- version = "3.21.82";
+ version = "3.22.02";
pname = "fldigi";
name = "${pname}-${version}";
src = fetchurl {
url = "http://www.w1hkj.com/downloads/${pname}/${name}.tar.gz";
- sha256 = "1q2fc1zm9kfsjir4g6fh95vmjdq984iyxfcs6q4gjqy1znhqcyqs";
+ sha256 = "1gry3r133j2x99h0ji56v6yjxzvbi0hb18p1lbkr9djzjvf591j3";
};
buildInputs = [ libXinerama gettext hamlib fltk13 libjpeg libpng portaudio
diff --git a/pkgs/applications/audio/fmit/default.nix b/pkgs/applications/audio/fmit/default.nix
new file mode 100644
index 00000000000..0c12778089b
--- /dev/null
+++ b/pkgs/applications/audio/fmit/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, fetchurl, alsaLib, cmake, fftw, freeglut, jack2, libXmu, qt4 }:
+
+stdenv.mkDerivation rec {
+ version = "0.99.5";
+ name = "fmit-${version}";
+
+ src = fetchurl {
+ url = "http://download.gna.org/fmit/${name}-Source.tar.bz2";
+ sha256 = "1rc84gi27jmq2smhk0y0p2xyypmsz878vi053iqns21k848g1491";
+ };
+
+ # Also update longDescription when adding/removing sound libraries
+ buildInputs = [ alsaLib cmake fftw freeglut jack2 libXmu qt4 ];
+
+ enableParallelBuilding = true;
+
+ meta = with stdenv.lib; {
+ description = "Free Musical Instrument Tuner";
+ longDescription = ''
+ Software for tuning musical instruments. Uses Qt as GUI library and
+ ALSA or JACK as sound input library.
+ '';
+ homepage = http://home.gna.org/fmit/index.html;
+ license = with licenses; gpl3Plus;
+ platforms = with platforms; linux;
+ maintainers = with maintainers; [ nckx ];
+ };
+}
diff --git a/pkgs/applications/audio/freewheeling/am_path_sdl.patch b/pkgs/applications/audio/freewheeling/am_path_sdl.patch
new file mode 100644
index 00000000000..2bc3b4f45ac
--- /dev/null
+++ b/pkgs/applications/audio/freewheeling/am_path_sdl.patch
@@ -0,0 +1,40 @@
+--- code-r100/configure.ac 2014-09-25 23:44:41.059174904 +0200
++++ code-r100.new/configure.ac 2014-09-26 01:37:18.507017390 +0200
+@@ -44,6 +44,8 @@
+ [AC_MSG_ERROR(CONFIG: You need libxml2-dev installed.
+ http://www.xmlsoft.org/)])
+
++PKG_CHECK_MODULES([libxml], [libxml-2.0])
++
+ AC_CHECK_LIB([m], [sqrt], , [AC_MSG_ERROR(CORE: You need libm installed)])
+ AC_CHECK_LIB([pthread], [pthread_self], , [AC_MSG_ERROR(CORE: You need libpthread installed)])
+
+@@ -79,12 +81,12 @@
+ echo "--- Enabling USB LCD display --";
+ fi
+
+-#SDL_VERSION=1.2.4
+-#AM_PATH_SDL($SDL_VERSION,
+-# :,
+-# AC_MSG_ERROR([VIDEO: *** SDL version $SDL_VERSION not found!
+-# http://www.libsdl.org/])
+-#)
++SDL_VERSION=1.2.4
++AM_PATH_SDL($SDL_VERSION,
++ :,
++ AC_MSG_ERROR([VIDEO: *** SDL version $SDL_VERSION not found!
++ http://www.libsdl.org/])
++)
+
+ AC_CHECK_LIB([vorbis], [main], ,
+ [AC_MSG_ERROR(AUDIO: You need libvorbis-dev installed.
+@@ -95,6 +97,9 @@
+ AC_CHECK_LIB([vorbisenc], [main], ,
+ [AC_MSG_ERROR(AUDIO: You need libvorbis-dev installed.
+ http://www.xiph.org/ogg/vorbis/)])
++AC_CHECK_LIB([ogg], [main], ,
++ [AC_MSG_ERROR(AUDIO: You need libogg-dev installed.
++ http://www.xiph.org/ogg/)])
+
+ AC_CHECK_LIB([sndfile], [main], ,
+ [AC_MSG_ERROR(AUDIO: you need libsndfile installed.
diff --git a/pkgs/applications/audio/freewheeling/default.nix b/pkgs/applications/audio/freewheeling/default.nix
new file mode 100644
index 00000000000..a3f356e75c4
--- /dev/null
+++ b/pkgs/applications/audio/freewheeling/default.nix
@@ -0,0 +1,44 @@
+{ stdenv, fetchsvn, pkgconfig, autoconf, automake, gnutls, freetype
+, SDL, SDL_gfx, SDL_ttf, liblo, libxml2, alsaLib, jack2, libvorbis
+, libsndfile, libogg
+}:
+
+stdenv.mkDerivation {
+ name = "freewheeling-100";
+
+ src = fetchsvn {
+ url = svn://svn.code.sf.net/p/freewheeling/code;
+ rev = 100;
+ sha256 = "1m6z7p93xyha25qma9bazpzbp04pqdv5h3yrv6851775xsyvzksv";
+ };
+
+ buildInputs = [
+ pkgconfig autoconf automake gnutls freetype SDL SDL_gfx SDL_ttf
+ liblo libxml2 jack2 alsaLib libvorbis libsndfile libogg
+ ];
+
+ preConfigure = "autoreconf -vfi";
+
+ patches = [ ./am_path_sdl.patch ./xml.patch ];
+
+ meta = {
+ description = "A live looping instrument with JACK and MIDI support";
+ longDescription = ''
+ Freewheeling allows us to build repetitive grooves
+ by sampling and directing loops from within spirited improvisation.
+
+ It works because, down to the core, it's built around
+ improv. We leave mice and menus, and dive into our own process
+ of making sound.
+
+ Freewheeling runs under Mac OS X and Linux, and is open source
+ software, released under the GNU GPL license.
+ '' ;
+
+ version = "r100";
+ homepage = "http://freewheeling.sourceforge.net";
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.sepi ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/freewheeling/xml.patch b/pkgs/applications/audio/freewheeling/xml.patch
new file mode 100644
index 00000000000..fd9d4fb39fe
--- /dev/null
+++ b/pkgs/applications/audio/freewheeling/xml.patch
@@ -0,0 +1,13 @@
+--- code-r100/src/Makefile.am 2014-09-25 23:44:41.043174832 +0200
++++ code-r100.new/src/Makefile.am 2014-09-26 01:21:03.750015888 +0200
+@@ -24,7 +24,8 @@
+
+ fweelindir = $(datadir)/fweelin
+
+-FWEELIN_CFLAGS = -I. -g -Wall -Wno-write-strings -Wno-non-virtual-dtor -D_REENTRANT -DPTHREADS -DNDEBUG -DVERSION=\"$(VERSION)\" -DFWEELIN_DATADIR=\"$(fweelindir)\" -DADDON_DIR=\"/usr/local/lib/jack\" -I/usr/include/freetype2 -I/usr/include/libxml2 -funroll-loops -finline-functions -fomit-frame-pointer -ffast-math -fexpensive-optimizations -fstrict-aliasing -falign-loops=2 -falign-jumps=2 -falign-functions=2 -O9
++XML_CFLAGS = `xml2-config --cflags`
++FWEELIN_CFLAGS = -I. -g -Wall -Wno-write-strings -Wno-non-virtual-dtor -D_REENTRANT -DPTHREADS -DNDEBUG -DVERSION=\"$(VERSION)\" -DFWEELIN_DATADIR=\"$(fweelindir)\" -DADDON_DIR=\"/usr/local/lib/jack\" -I/usr/include/freetype2 $(XML_CFLAGS) -funroll-loops -finline-functions -fomit-frame-pointer -ffast-math -fexpensive-optimizations -fstrict-aliasing -falign-loops=2 -falign-jumps=2 -falign-functions=2 -O9
+
+ AM_CFLAGS = $(CFLAGS) $(FWEELIN_CFLAGS)
+-AM_CXXFLAGS = $(CFLAGS) $(CXXFLAGS) $(FWEELIN_CFLAGS)
++AM_CXXFLAGS = $(CFLAGS) $(CXXFLAGS) $(FWEELIN_CFLAGS) ${libxml2_CFLAGS}
diff --git a/pkgs/applications/audio/game-music-emu/default.nix b/pkgs/applications/audio/game-music-emu/default.nix
new file mode 100644
index 00000000000..60d9c0e7b12
--- /dev/null
+++ b/pkgs/applications/audio/game-music-emu/default.nix
@@ -0,0 +1,21 @@
+{ stdenv, fetchurl, cmake }:
+
+stdenv.mkDerivation rec {
+ version = "0.6.0";
+ name = "game-music-emu-${version}";
+
+ src = fetchurl {
+ url = "https://game-music-emu.googlecode.com/files/${name}.tar.bz2";
+ sha256 = "11s9l938nxbrk7qb2k1ppfgizcz00cakbxgv0gajc6hyqv882vjh";
+ };
+
+ buildInputs = [ cmake ];
+
+ meta = with stdenv.lib; {
+ homepage = https://code.google.com/p/game-music-emu/;
+ description = "A collection of video game music file emulators";
+ license = licenses.lgpl21Plus;
+ platforms = platforms.all;
+ maintainers = [ ];
+ };
+}
diff --git a/pkgs/applications/audio/gmpc/default.nix b/pkgs/applications/audio/gmpc/default.nix
index 728155c02bd..7cc8aeda367 100644
--- a/pkgs/applications/audio/gmpc/default.nix
+++ b/pkgs/applications/audio/gmpc/default.nix
@@ -1,5 +1,6 @@
{ stdenv, fetchurl, libtool, intltool, pkgconfig, glib
, gtk, curl, mpd_clientlib, libsoup, gob2, vala, libunique
+, libSM, libICE, sqlite
}:
stdenv.mkDerivation rec {
@@ -12,6 +13,7 @@ stdenv.mkDerivation rec {
url = http://download.sarine.nl/Programs/gmpc/11.8/libmpd-11.8.17.tar.gz;
sha256 = "10vspwsgr8pwf3qp2bviw6b2l8prgdiswgv7qiqiyr0h1mmk487y";
};
+ patches = [ ./libmpd-11.8.17-remove-strndup.patch ];
buildInputs = [ pkgconfig glib ];
};
@@ -22,7 +24,7 @@ stdenv.mkDerivation rec {
buildInputs = [
libtool intltool pkgconfig glib gtk curl mpd_clientlib libsoup
- libunique libmpd gob2 vala
+ libunique libmpd gob2 vala libSM libICE sqlite
];
meta = with stdenv.lib; {
diff --git a/pkgs/applications/audio/gmpc/libmpd-11.8.17-remove-strndup.patch b/pkgs/applications/audio/gmpc/libmpd-11.8.17-remove-strndup.patch
new file mode 100644
index 00000000000..ad4fdc02ef3
--- /dev/null
+++ b/pkgs/applications/audio/gmpc/libmpd-11.8.17-remove-strndup.patch
@@ -0,0 +1,15 @@
+diff --git a/src/libmpd-internal.h b/src/libmpd-internal.h
+index c84c3a4..51be441 100644
+--- a/src/libmpd-internal.h
++++ b/src/libmpd-internal.h
+@@ -206,10 +206,6 @@ int mpd_unlock_conn(MpdObj *mi);
+ MpdData * mpd_misc_sort_tag_list(MpdData *data);
+
+
+-#ifndef HAVE_STRNDUP
+-char * strndup (const char *s, size_t n);
+-#endif
+-
+ int mpd_server_get_allowed_commands(MpdObj *mi);
+ typedef enum _MpdSearchType {
+ MPD_SEARCH_TYPE_NONE,
diff --git a/pkgs/applications/audio/gnaural/default.nix b/pkgs/applications/audio/gnaural/default.nix
new file mode 100644
index 00000000000..c9746590566
--- /dev/null
+++ b/pkgs/applications/audio/gnaural/default.nix
@@ -0,0 +1,17 @@
+{ stdenv, fetchurl, pkgconfig, gtk2, libsndfile, portaudio }:
+
+stdenv.mkDerivation rec {
+ name = "gnaural-1.0.20110606";
+ buildInputs = [ pkgconfig gtk2 libsndfile portaudio ];
+ src = fetchurl {
+ url = "mirror://sourceforge/gnaural/Gnaural/${name}.tar.gz";
+ sha256 = "0p9rasz1jmxf16vnpj17g3vzdjygcyz3l6nmbq6wr402l61f1vy5";
+ };
+ meta = with stdenv.lib;
+ { description = "Auditory binaural-beat generator";
+ homepage = http://gnaural.sourceforge.net/;
+ licenses = licenses.gpl2;
+ maintainers = [ maintainers.emery ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/google-musicmanager/default.nix b/pkgs/applications/audio/google-musicmanager/default.nix
index 8cff94c25d9..e7c513febf5 100644
--- a/pkgs/applications/audio/google-musicmanager/default.nix
+++ b/pkgs/applications/audio/google-musicmanager/default.nix
@@ -4,8 +4,8 @@
assert stdenv.system == "x86_64-linux" || stdenv.system == "1686-linux";
stdenv.mkDerivation rec {
- debversion = "beta_1.0.84.1107-r0";
- version = "1.0.84.1107-beta-r0"; # friendly to nix-env version sorting algo
+ debversion = "beta_1.0.129.6633-r0";
+ version = "beta_1.0.129.6633-r0"; # friendly to nix-env version sorting algo
product = "google-musicmanager";
name = "${product}-${version}";
@@ -16,12 +16,12 @@ stdenv.mkDerivation rec {
src = if stdenv.system == "x86_64-linux"
then fetchurl {
- url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/${product}-beta/${product}-${debversion}_amd64.deb";
- sha256 = "0irlrspw508b1s9i5d1mddpp2x9w1ny3svf27gxf8pmwbiyd1cyi";
+ url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_amd64.deb";
+ sha256 = "1fq2p721mzv8nd4dq6i9xiqvvqd5ak3v142vsxchg6yn14a9kbvr";
}
else fetchurl {
- url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/${product}-beta/${product}-${debversion}_i386.deb";
- sha256 = "13pfsjvaygap6axrlbfhyk1h8377xmwi47x4af6j57qq6z7329rg";
+ url = "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/google-musicmanager-${version}_i386.deb";
+ sha256 = "7914e3e6e2adb2e952ebaf383db5e04727c29cfa83401007f29977f6c5ff6873";
};
unpackPhase = ''
@@ -33,8 +33,8 @@ stdenv.mkDerivation rec {
buildPhase = ''
patchelf \
- --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
- --set-rpath "$out/opt/google/musicmanager:${readline}/lib:${ncurses}/lib:${stdenv.gcc.libc}/lib:${qt48}/lib:${stdenv.gcc.gcc}/lib:${libidn}/lib:${expat}/lib:${flac}/lib:${libvorbis}/lib" opt/google/musicmanager/MusicManager
+ --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+ --set-rpath "$out/opt/google/musicmanager:${readline}/lib:${ncurses}/lib:${stdenv.cc.libc}/lib:${qt48}/lib:${stdenv.cc.cc}/lib:${libidn}/lib:${expat}/lib:${flac}/lib:${libvorbis}/lib" opt/google/musicmanager/MusicManager
'';
dontPatchELF = true;
diff --git a/pkgs/applications/audio/gpodder/default.nix b/pkgs/applications/audio/gpodder/default.nix
index 19b61ebc76d..e8c14a9c763 100644
--- a/pkgs/applications/audio/gpodder/default.nix
+++ b/pkgs/applications/audio/gpodder/default.nix
@@ -1,5 +1,5 @@
{ pkgs, stdenv, fetchurl, python, buildPythonPackage, pythonPackages, mygpoclient, intltool,
- ipodSupport ? true, libgpod, gpodderHome ? "", gpodderDownloadDir ? "" }:
+ ipodSupport ? true, libgpod, gnome3, hicolor_icon_theme }:
with pkgs.lib;
@@ -7,16 +7,23 @@ let
inherit (pythonPackages) coverage feedparser minimock sqlite3 dbus pygtk eyeD3;
in buildPythonPackage rec {
- name = "gpodder-3.7.0";
+ name = "gpodder-3.8.3";
src = fetchurl {
url = "http://gpodder.org/src/${name}.tar.gz";
- sha256 = "fa90ef4bdd3fd9eef95404f7f43f70912ae3ab4f8d24078484a2f3e11b14dc47";
+ sha256 = "8ac120a6084bded6bc88ecadbbc9df54a85f44ef4507f73a76de1d7a5574303c";
};
- buildInputs = [ coverage feedparser minimock sqlite3 mygpoclient intltool ];
+ buildInputs = [
+ coverage feedparser minimock sqlite3 mygpoclient intltool
+ gnome3.gnome_themes_standard gnome3.gnome_icon_theme
+ gnome3.gnome_icon_theme_symbolic hicolor_icon_theme
+ gnome3.gsettings_desktop_schemas
+ ];
- propagatedBuildInputs = [ feedparser dbus mygpoclient sqlite3 pygtk eyeD3 ]
+ propagatedUserEnvPkgs = [ gnome3.gnome_themes_standard ];
+
+ pythonPath = [ feedparser dbus mygpoclient sqlite3 pygtk eyeD3 ]
++ stdenv.lib.optional ipodSupport libgpod;
postPatch = "sed -ie 's/PYTHONPATH=src/PYTHONPATH=\$(PYTHONPATH):src/' makefile";
@@ -25,8 +32,29 @@ in buildPythonPackage rec {
preFixup = ''
wrapProgram $out/bin/gpodder \
- ${optionalString (gpodderHome != "") "--set GPODDER_HOME ${gpodderHome}"} \
- ${optionalString (gpodderDownloadDir != "") "--set GPODDER_DOWNLOAD_DIR ${gpodderDownloadDir}"}
+ --prefix XDG_DATA_DIRS : "${gnome3.gnome_themes_standard}/share:$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH"
+ '';
+
+ # The `wrapPythonPrograms` script in the postFixup phase breaks gpodder. The
+ # easiest way to fix this is to call wrapPythonPrograms and then to clean up
+ # the wrapped file.
+ postFixup = ''
+ wrapPythonPrograms
+
+ if test -e $out/nix-support/propagated-build-inputs; then
+ ln -s $out/nix-support/propagated-build-inputs $out/nix-support/propagated-user-env-packages
+ fi
+
+ createBuildInputsPth build-inputs "$buildInputStrings"
+ for inputsfile in propagated-build-inputs propagated-native-build-inputs; do
+ if test -e $out/nix-support/$inputsfile; then
+ createBuildInputsPth $inputsfile "$(cat $out/nix-support/$inputsfile)"
+ fi
+ done
+
+ sed -i "$out/bin/..gpodder-wrapped-wrapped" -e '{
+ /import sys; sys.argv/d
+ }'
'';
installPhase = "DESTDIR=/ PREFIX=$out make install";
@@ -38,7 +66,7 @@ in buildPythonPackage rec {
for you. Listen directly on your computer or on your mobile devices.
'';
homepage = "http://gpodder.org/";
- license = "GPLv3";
+ license = stdenv.lib.licenses.gpl3;
platforms = stdenv.lib.platforms.linux ++ stdenv.lib.platforms.darwin;
maintainers = [ stdenv.lib.maintainers.skeidel ];
};
diff --git a/pkgs/applications/audio/gtkpod/default.nix b/pkgs/applications/audio/gtkpod/default.nix
index 80a7cf52cd8..9c08b2ab6d7 100644
--- a/pkgs/applications/audio/gtkpod/default.nix
+++ b/pkgs/applications/audio/gtkpod/default.nix
@@ -1,11 +1,8 @@
{ stdenv, fetchurl, pkgconfig, makeWrapper, intltool, libgpod, curl, flac,
- gnome3_12, gtk3, glib, gettext, perl, perlXMLParser , libglade, flex, libid3tag,
+ gnome, gtk3, glib, gettext, perl, perlXMLParser, flex, libglade, libid3tag,
libvorbis, hicolor_icon_theme, gdk_pixbuf }:
-let
- gnome = gnome3_12;
-
-in stdenv.mkDerivation rec {
+stdenv.mkDerivation rec {
version = "2.1.4";
name = "gtkpod-${version}";
diff --git a/pkgs/applications/audio/guitarix/default.nix b/pkgs/applications/audio/guitarix/default.nix
index 777c0ddb2e3..984d666ab95 100644
--- a/pkgs/applications/audio/guitarix/default.nix
+++ b/pkgs/applications/audio/guitarix/default.nix
@@ -1,26 +1,43 @@
-{ stdenv, fetchurl, avahi, boost, fftw, gettext, glib, glibmm, gtk
-, gtkmm, intltool, jack2, ladspaH, librdf, libsndfile, lv2
-, pkgconfig, python }:
+{ stdenv, fetchurl, gettext, intltool, pkgconfig, python
+, avahi, bluez, boost, eigen, fftw, glib, glibmm, gtk, gtkmm, jack2
+, ladspaH, librdf, libsndfile, lilv, lv2, serd, sord, sratom
+, optimizationSupport ? false # Enable support for native CPU extensions
+}:
+
+let
+ inherit (stdenv.lib) optional;
+in
stdenv.mkDerivation rec {
name = "guitarix-${version}";
- version = "0.28.3";
+ version = "0.32.3";
src = fetchurl {
url = "mirror://sourceforge/guitarix/guitarix2-${version}.tar.bz2";
- sha256 = "0ks5avylyicqfj9l1wf4gj62i8m6is2jmp0h11h5l2wbg3xiwxjd";
+ sha256 = "1ybc5jk7fj6n8qh9ajzl1f6fzdmzab4nwjrh4fsylm94dn1jv0if";
};
+ nativeBuildInputs = [ gettext intltool pkgconfig python ];
+
buildInputs = [
- avahi boost fftw gettext glib glibmm gtk gtkmm intltool jack2
- ladspaH librdf libsndfile lv2 pkgconfig python
+ avahi bluez boost eigen fftw glib glibmm gtk gtkmm jack2
+ ladspaH librdf libsndfile lilv lv2 serd sord sratom
];
- configurePhase = "python waf configure --prefix=$out";
+ configureFlags = [
+ "--shared-lib"
+ "--no-desktop-update"
+ "--no-faust" # Need to package a release of faust, 0.9.58 or 0.9.65
+ "--enable-nls"
+ "--includeresampler" # Zita-resampler not packaged, use vendored version
+ "--includeconvolver" # Zita-convolver not packaged, use vendored version
+ ] ++ optional optimizationSupport "--optimization";
- buildPhase = "python waf build";
+ configurePhase = ''python waf configure --prefix=$out $configureFlags'';
- installPhase = "python waf install";
+ buildPhase = ''python waf build'';
+
+ installPhase = ''python waf install'';
meta = with stdenv.lib; {
description = "A virtual guitar amplifier for Linux running with JACK";
diff --git a/pkgs/applications/audio/hydrogen/default.nix b/pkgs/applications/audio/hydrogen/default.nix
index 10f15f5882c..434f683bd5c 100644
--- a/pkgs/applications/audio/hydrogen/default.nix
+++ b/pkgs/applications/audio/hydrogen/default.nix
@@ -1,35 +1,19 @@
-{ stdenv, fetchurl, alsaLib, boost, glib, jack2, ladspaPlugins
-, libarchive, liblrdf , libsndfile, pkgconfig, qt4, scons, subversion }:
+{ stdenv, fetchurl, alsaLib, boost, cmake, glib, jack2, libarchive
+, liblrdf, libsndfile, pkgconfig, qt4 }:
stdenv.mkDerivation rec {
- version = "0.9.5.1";
+ version = "0.9.6.1";
name = "hydrogen-${version}";
src = fetchurl {
- url = "mirror://sourceforge/hydrogen/hydrogen-${version}.tar.gz";
- sha256 = "1fvyp6gfzcqcc90dmaqbm11p272zczz5pfz1z4lj33nfr7z0bqgb";
+ url = "https://github.com/hydrogen-music/hydrogen/archive/${version}.tar.gz";
+ sha256 = "0vxnaqfmcv7hhk0cj67imdcqngspnck7f0wfmvhfgfqa7x1xznll";
};
buildInputs = [
- alsaLib boost glib jack2 ladspaPlugins libarchive liblrdf
- libsndfile pkgconfig qt4 scons subversion
+ alsaLib boost cmake glib jack2 libarchive liblrdf libsndfile pkgconfig qt4
];
- patches = [ ./scons-env.patch ];
-
- postPatch = ''
- sed -e 's#/usr/lib/ladspa#${ladspaPlugins}/lib/ladspa#' -i libs/hydrogen/src/preferences.cpp
- sed '/\/usr/d' -i libs/hydrogen/src/preferences.cpp
- sed "s#pkg_ver.rstrip().split('.')#pkg_ver.rstrip().split('.')[:3]#" -i Sconstruct
- '';
-
- # why doesn't scons find librdf?
- buildPhase = ''
- scons prefix=$out libarchive=1 lrdf=0 install
- '';
-
- installPhase = ":";
-
meta = with stdenv.lib; {
description = "Advanced drum machine";
homepage = http://www.hydrogen-music.org;
diff --git a/pkgs/applications/audio/hydrogen/scons-env.patch b/pkgs/applications/audio/hydrogen/scons-env.patch
deleted file mode 100644
index ebc17f67872..00000000000
--- a/pkgs/applications/audio/hydrogen/scons-env.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- hydrogen-0.9.5/Sconstruct 2011-03-15 13:22:35.000000000 +0100
-+++ hydrogen-0.9.5/Sconstruct 2011-04-17 16:06:54.000000000 +0200
-@@ -178,7 +178,7 @@
-
- includes.append( "libs/hydrogen/include" )
-
-- env = Environment( options = opts )
-+ env = Environment( options = opts, ENV = os.environ )
-
-
- #location of qt4.py
-@@ -298,7 +298,6 @@
-
- for N in glob.glob('./data/i18n/hydrogen.*'):
- env.Alias(target="install", source=env.Install(dir= env['DESTDIR'] + env['prefix'] + '/share/hydrogen/data/i18n', source=N))
-- env.Alias(target="install", source=env.Install(dir= env['DESTDIR'] + env['prefix'] + '/share/hydrogen/data', source="./data/img"))
-
- #add every img in ./data/img to the install list.
- os.path.walk("./data/img/",install_images,env)
-@@ -379,7 +379,7 @@
-
- includes, a , b = get_platform_flags( opts )
-
--env = Environment(options = opts, CPPPATH = includes)
-+env = Environment(options = opts, ENV = os.environ)
-
-
- Help(opts.GenerateHelpText(env))
diff --git a/pkgs/applications/audio/ingen/default.nix b/pkgs/applications/audio/ingen/default.nix
index ac46ff6140c..d4abbbe0083 100644
--- a/pkgs/applications/audio/ingen/default.nix
+++ b/pkgs/applications/audio/ingen/default.nix
@@ -1,27 +1,37 @@
{ stdenv, fetchsvn, boost, ganv, glibmm, gtk, gtkmm, jack2, lilv
-, lv2, pkgconfig, python, raul, serd, sord, sratom, suil
+, lv2, makeWrapper, pkgconfig, python, raul, rdflib, serd, sord, sratom
+, suil
}:
stdenv.mkDerivation rec {
name = "ingen-svn-${rev}";
- rev = "5317";
+ rev = "5490";
src = fetchsvn {
url = "http://svn.drobilla.net/lad/trunk/ingen";
rev = rev;
- sha256 = "0zm3wbv9qsingjyr95nwin3khmnf3wq3fz2xa6p420dpcy6qnl4x";
+ sha256 = "09h2mrkzpwzhhyqy21xr7jhfbl82gmqfyj0lzhnjsrab8z56yzk6";
};
buildInputs = [
- boost ganv glibmm gtk gtkmm jack2 lilv lv2 pkgconfig python
- raul serd sord sratom suil
+ boost ganv glibmm gtk gtkmm jack2 lilv lv2 makeWrapper pkgconfig
+ python raul serd sord sratom suil
];
configurePhase = "python waf configure --prefix=$out";
+ propagatedBuildInputs = [ rdflib ];
+
buildPhase = "python waf";
- installPhase = "python waf install";
+ installPhase = ''
+ python waf install
+ for program in ingenams ingenish
+ do
+ wrapProgram $out/bin/$program \
+ --prefix PYTHONPATH : $out/lib/python${python.majorVersion}/site-packages:$PYTHONPATH
+ done
+ '';
meta = with stdenv.lib; {
description = "A modular audio processing system using JACK and LV2 or LADSPA plugins";
diff --git a/pkgs/applications/audio/jalv/default.nix b/pkgs/applications/audio/jalv/default.nix
index 70ef5bdec5c..bf01fe1a935 100644
--- a/pkgs/applications/audio/jalv/default.nix
+++ b/pkgs/applications/audio/jalv/default.nix
@@ -3,11 +3,11 @@
stdenv.mkDerivation rec {
name = "jalv-${version}";
- version = "1.4.4";
+ version = "1.4.6";
src = fetchurl {
url = "http://download.drobilla.net/${name}.tar.bz2";
- sha256 = "1iql1r52rmf87q6jkxhcxa3lpq7idzzg55ma91wphywyvh29q7lf";
+ sha256 = "1f1hcq74n3ziw8bk97mn5a1vgw028dxikv3fchaxd430pbbhqgl9";
};
buildInputs = [
diff --git a/pkgs/applications/audio/keyfinder-cli/default.nix b/pkgs/applications/audio/keyfinder-cli/default.nix
new file mode 100644
index 00000000000..dca72f22b49
--- /dev/null
+++ b/pkgs/applications/audio/keyfinder-cli/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, fetchFromGitHub, libav, libkeyfinder }:
+
+let version = "20150130"; in
+stdenv.mkDerivation rec {
+ name = "keyfinder-cli-${version}";
+
+ src = fetchFromGitHub {
+ repo = "keyfinder-cli";
+ owner = "EvanPurkhiser";
+ rev = "e8a20e73f8a465a6c3c9e71dabf4b636244a9b0c";
+ sha256 = "0x198ijr6wgzq24642s4pz5zxn4gvcc7dxmb6d1bfn3dwzi3j8lp";
+ };
+
+ meta = with stdenv.lib; {
+ description = "Musical key detection for digital audio (command-line tool)";
+ longDescription = ''
+ This small utility is the automation-oriented DJ's best friend. By making
+ use of Ibrahim Sha'ath's high quality libKeyFinder library, it can be
+ used to estimate the musical key of many different audio formats.
+ '';
+ homepage = https://github.com/EvanPurkhiser/keyfinder-cli;
+ license = with licenses; gpl3Plus;
+ platforms = with platforms; linux;
+ maintainers = with maintainers; [ nckx ];
+ };
+
+ buildInputs = [ libav libkeyfinder ];
+
+ makeFlagsArray = "PREFIX=$(out)";
+
+ enableParallelBuilding = true;
+}
diff --git a/pkgs/applications/audio/keyfinder/default.nix b/pkgs/applications/audio/keyfinder/default.nix
new file mode 100644
index 00000000000..33ce627e56e
--- /dev/null
+++ b/pkgs/applications/audio/keyfinder/default.nix
@@ -0,0 +1,42 @@
+{ stdenv, fetchFromGitHub, libav_0_8, libkeyfinder, qt5, taglib }:
+
+stdenv.mkDerivation rec {
+ version = "1.25-17-gf670607";
+ name = "keyfinder-${version}";
+
+ src = fetchFromGitHub {
+ repo = "is_KeyFinder";
+ owner = "ibsh";
+ rev = "f6706074435ac14c5238ee3f0dd22ac22d72af9c";
+ sha256 = "1sfnywc6jdpm03344i6i4pz13mqa4i5agagj4k6252m63cqmjkrc";
+ };
+
+ meta = with stdenv.lib; {
+ description = "Musical key detection for digital audio (graphical UI)";
+ longDescription = ''
+ KeyFinder is an open source key detection tool, for DJs interested in
+ harmonic and tonal mixing. Designed primarily for electronic and dance
+ music, it is highly configurable and can be applied to many genres. It
+ supports a huge range of codecs thanks to LibAV, and writes to metadata
+ tags using TagLib. It's intended to be very focused: no library
+ management, no track suggestions, no media player. Just a fast,
+ efficient workflow tool.
+ '';
+ homepage = http://www.ibrahimshaath.co.uk/keyfinder/;
+ license = with licenses; gpl3Plus;
+ platforms = with platforms; linux;
+ maintainers = with maintainers; [ nckx ];
+ };
+
+ # TODO: upgrade libav when "Audio sample format conversion failed" is fixed
+ buildInputs = [ libav_0_8 libkeyfinder qt5.base qt5.xmlpatterns taglib ];
+
+ configurePhase = ''
+ substituteInPlace is_KeyFinder.pro \
+ --replace "keyfinder.0" "keyfinder" \
+ --replace '$$[QT_INSTALL_PREFIX]' "$out"
+ qmake
+ '';
+
+ enableParallelBuilding = true;
+}
diff --git a/pkgs/applications/audio/kid3/default.nix b/pkgs/applications/audio/kid3/default.nix
new file mode 100644
index 00000000000..58a64758c35
--- /dev/null
+++ b/pkgs/applications/audio/kid3/default.nix
@@ -0,0 +1,74 @@
+{ stdenv, fetchurl
+, pkgconfig, cmake, perl, ffmpeg
+, docbook_xml_dtd_45, docbook_xsl, libxslt
+, phonon, automoc4, chromaprint, id3lib
+, taglib, mp4v2, flac, libogg, libvorbis
+, qt, zlib, readline
+, makeWrapper
+}:
+
+stdenv.mkDerivation rec {
+
+ name = "kid3-${version}";
+ version = "3.1.2";
+
+ src = fetchurl {
+ url = "http://downloads.sourceforge.net/project/kid3/kid3/${version}/${name}.tar.gz";
+ sha256 = "0ik2bxg2im7nwcgi85g2dj148n80mfhks20rsxnzazl7afk9fl08";
+ };
+
+ buildInputs = with stdenv.lib;
+ [ pkgconfig cmake perl ffmpeg docbook_xml_dtd_45 docbook_xsl libxslt
+ phonon automoc4 chromaprint id3lib taglib mp4v2 flac libogg libvorbis
+ qt zlib readline makeWrapper ];
+
+ cmakeFlags = [ "-DCMAKE_BUILD_TYPE=Release" "-DWITH_APPS=Qt;CLI" ];
+ NIX_LDFLAGS = "-lm -lpthread";
+
+ preConfigure = ''
+ export DOCBOOKDIR="${docbook_xsl}/xml/xsl/docbook/"
+ '';
+
+ postInstall = ''
+ wrapProgram $out/bin/kid3-qt --prefix QT_PLUGIN_PATH : $out/lib/qt4/plugins
+ '';
+
+ meta = with stdenv.lib; {
+ description = "A simple and powerful audio tag editor";
+ longDescription = ''
+ If you want to easily tag multiple MP3, Ogg/Vorbis, FLAC, MPC,
+ MP4/AAC, MP2, Opus, Speex, TrueAudio, WavPack, WMA, WAV and AIFF
+ files (e.g. full albums) without typing the same information
+ again and again and have control over both ID3v1 and ID3v2 tags,
+ then Kid3 is the program you are looking for.
+
+ With Kid3 you can:
+ - Edit ID3v1.1 tags;
+ - Edit all ID3v2.3 and ID3v2.4 frames;
+ - Convert between ID3v1.1, ID3v2.3 and ID3v2.4 tags
+ - Edit tags in MP3, Ogg/Vorbis, FLAC, MPC, MP4/AAC, MP2, Opus,
+ Speex, TrueAudio, WavPack, WMA, WAV, AIFF files and tracker
+ modules (MOD, S3M, IT, XM);
+ - Edit tags of multiple files, e.g. the artist, album, year and
+ genre of all files of an album typically have the same values
+ and can be set together;
+ - Generate tags from filenames;
+ - Generate tags from the contents of tag fields;
+ - Generate filenames from tags;
+ - Rename and create directories from tags;
+ - Generate playlist files;
+ - Automatically convert upper and lower case and replace strings;
+ - Import from gnudb.org, TrackType.org, MusicBrainz, Discogs,
+ Amazon and other sources of album data;
+ - Export tags as CSV, HTML, playlists, Kover XML and in other
+ formats;
+ - Edit synchronized lyrics and event timing codes, import and
+ export LRC files
+ '';
+ homepage = http://kid3.sourceforge.net/;
+ license = licenses.lgpl2Plus;
+ maintainers = [ maintainers.AndersonTorres ];
+ };
+}
+
+# TODO: Qt5 support
diff --git a/pkgs/applications/audio/lame/default.nix b/pkgs/applications/audio/lame/default.nix
deleted file mode 100644
index 09b553a099c..00000000000
--- a/pkgs/applications/audio/lame/default.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{stdenv, fetchurl, nasm}:
-
-stdenv.mkDerivation rec {
- name = "lame-3.99.5";
- src = fetchurl {
- url = "mirror://sourceforge/lame/${name}.tar.gz";
- sha256 = "1zr3kadv35ii6liia0bpfgxpag27xcivp571ybckpbz4b10nnd14";
- };
-
- buildInputs = [ nasm ];
-
- configureFlags = [ "--enable-nasm" ];
-
- # Either disable static, or fix the rpath of 'lame' for it to point
- # properly to the libmp3lame shared object.
- dontDisableStatic = true;
-}
diff --git a/pkgs/applications/audio/lmms/default.nix b/pkgs/applications/audio/lmms/default.nix
index dd0649811bb..6d28c038f23 100644
--- a/pkgs/applications/audio/lmms/default.nix
+++ b/pkgs/applications/audio/lmms/default.nix
@@ -1,24 +1,22 @@
-{ stdenv, fetchurl, SDL, alsaLib, cmake, fftwSinglePrec, jack2, libogg
-, libsamplerate, libsndfile, pkgconfig, pulseaudio, qt4, freetype
+{ stdenv, fetchurl, SDL, alsaLib, cmake, fftwSinglePrec, fluidsynth
+, fltk13, jack2, libvorbis , libsamplerate, libsndfile, pkgconfig
+, pulseaudio, qt4, freetype
}:
stdenv.mkDerivation rec {
name = "lmms-${version}";
- version = "0.4.15";
+ version = "1.1.3";
src = fetchurl {
- url = "mirror://sourceforge/lmms/${name}.tar.bz2";
- sha256 = "02q2gbsqwk3hf9kvzz58a5bxmlb4cfr2mzy41wdvbxxdm2pcl101";
+ url = "https://github.com/LMMS/lmms/archive/v${version}.tar.gz";
+ sha256 = "1g76z7ha3hd53vbqaq9n1qg6s3lw8zzaw51iny6y2bz0j1xqwcsr";
};
buildInputs = [
- SDL alsaLib cmake fftwSinglePrec jack2 libogg libsamplerate
- libsndfile pkgconfig pulseaudio qt4
+ SDL alsaLib cmake fftwSinglePrec fltk13 fluidsynth jack2
+ libsamplerate libsndfile libvorbis pkgconfig pulseaudio qt4
];
- # work around broken build system of 0.4.*
- NIX_CFLAGS_COMPILE = "-I${freetype}/include/freetype2";
-
enableParallelBuilding = true;
meta = with stdenv.lib; {
diff --git a/pkgs/applications/audio/meters_lv2/default.nix b/pkgs/applications/audio/meters_lv2/default.nix
new file mode 100644
index 00000000000..3b7a5bc685c
--- /dev/null
+++ b/pkgs/applications/audio/meters_lv2/default.nix
@@ -0,0 +1,47 @@
+{ stdenv, fetchurl, pkgconfig
+, lv2, mesa, gtk2, cairo, pango, fftw }:
+
+let
+ version = "0.8.1";
+ name = "meters.lv2-${version}";
+
+ # robtk submodule is pegged to this version
+ robtkVersion = "0.3.0";
+ robtkName = "robtk-${robtkVersion}";
+
+ src = fetchurl {
+ name = "${name}.tar.gz";
+ url = "https://github.com/x42/meters.lv2/archive/v${version}.tar.gz";
+ sha256 = "142dg0j34mv5b0agajj2x1n9kgsmkfh08n1cjzk0j8n4xk2wb6ri";
+ };
+
+ robtkSrc = fetchurl {
+ name = "${robtkName}.tar.gz";
+ url = "https://github.com/x42/robtk/archive/v${robtkVersion}.tar.gz";
+ sha256 = "1ny89i2sgga56k7fxskp9y8sb7pfhp6wgw5mni842p19z6q7h8rq";
+ };
+
+in
+stdenv.mkDerivation {
+ inherit name;
+
+ buildInputs = [ pkgconfig lv2 mesa gtk2 cairo pango fftw ];
+
+ srcs = [ src robtkSrc ];
+ sourceRoot = name;
+
+ postUnpack = "mv ${robtkName}/* ${name}/robtk"; # */
+
+ postPatch = "sed -i 's/fftw3f/fftw3/' Makefile";
+
+ preConfigure = "makeFlagsArray=( PREFIX=$out )";
+ meter_VERSION = version;
+
+ meta = with stdenv.lib;
+ { description = "Collection of audio level meters with GUI in LV2 plugin format";
+ homepage = http://x42.github.io/meters.lv2/;
+ maintainers = with maintainers; [ emery ];
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/mikmod/default.nix b/pkgs/applications/audio/mikmod/default.nix
index f38ff469731..58a83dafe69 100644
--- a/pkgs/applications/audio/mikmod/default.nix
+++ b/pkgs/applications/audio/mikmod/default.nix
@@ -1,10 +1,11 @@
{ stdenv, fetchurl, libmikmod, ncurses }:
stdenv.mkDerivation rec {
- name = "mikmod-3.2.2";
+ name = "mikmod-3.2.6";
+
src = fetchurl {
- url = "http://mikmod.shlomifish.org/files/${name}.tar.gz";
- sha256 = "105vl1kyah588wpbpq6ck1wlr0jj55l2ps72q5i01gs9px8ncmp8";
+ url = "http://downloads.sourceforge.net/project/mikmod/mikmod/3.2.6/mikmod-3.2.6.tar.gz";
+ sha256 = "0wr61raj10rpl64mk3x9g3rwys898fbzyg93c6mrz89nvc74wm04";
};
buildInputs = [ libmikmod ncurses ];
diff --git a/pkgs/applications/audio/milkytracker/default.nix b/pkgs/applications/audio/milkytracker/default.nix
index eadbaabcf56..d5d7ea7be76 100644
--- a/pkgs/applications/audio/milkytracker/default.nix
+++ b/pkgs/applications/audio/milkytracker/default.nix
@@ -35,7 +35,7 @@ stdenv.mkDerivation rec {
buildInputs = [ SDL alsaLib autoconf automake jack2 perl zlib zziplib ];
meta = {
- description = "Music tracker application, similar to Fasttracker II.";
+ description = "Music tracker application, similar to Fasttracker II";
homepage = http://milkytracker.org;
license = stdenv.lib.licenses.gpl3Plus;
platforms = [ "x86_64-linux" "i686-linux" ];
diff --git a/pkgs/applications/audio/mimms/default.nix b/pkgs/applications/audio/mimms/default.nix
new file mode 100644
index 00000000000..b337dbf6d82
--- /dev/null
+++ b/pkgs/applications/audio/mimms/default.nix
@@ -0,0 +1,31 @@
+{ fetchurl, stdenv, pythonPackages, libmms }:
+
+let version = "3.2";
+in
+ pythonPackages.buildPythonPackage {
+ name = "mimms-${version}";
+ src = fetchurl {
+ url = "http://download.savannah.gnu.org/releases/mimms/mimms-${version}.tar.bz2";
+ sha256 = "0zmcd670mpq85cs3nvdq3i805ba0d1alqahfy1m9cpf7kxrivfml";
+ };
+
+ postInstall = ''
+ wrapProgram $out/bin/mimms \
+ --prefix LD_LIBRARY_PATH : ${libmms}/lib
+ '';
+
+ meta = {
+ homepage = https://savannah.nongnu.org/projects/mimms/;
+ license = stdenv.lib.licenses.gpl3;
+ description = "An mms (e.g. mms://) stream downloader";
+
+ longDescription = ''
+ mimms is a program designed to allow you to download streams
+ using the MMS protocol and save them to your computer, as
+ opposed to watching them live. Similar functionality is
+ available in full media player suites such as Xine, MPlayer,
+ and VLC, but mimms is quick and easy to use and, for the time
+ being, remains a useful program.
+ '';
+ };
+ }
diff --git a/pkgs/applications/audio/moc/default.nix b/pkgs/applications/audio/moc/default.nix
index 5c6a1d6ac54..a87e74dc87c 100644
--- a/pkgs/applications/audio/moc/default.nix
+++ b/pkgs/applications/audio/moc/default.nix
@@ -1,27 +1,27 @@
{ stdenv, fetchurl, ncurses, pkgconfig, alsaLib, flac, libmad, speex, ffmpeg
-, libvorbis, mpc, libsndfile, jack2, db, libmodplug, timidity, libid3tag
+, libvorbis, libmpc, libsndfile, jack2, db, libmodplug, timidity, libid3tag
, libtool
}:
stdenv.mkDerivation rec {
name = "moc-${version}";
- version = "2.5.0-beta2";
+ version = "2.5.0";
src = fetchurl {
- url = "http://ftp.daper.net/pub/soft/moc/unstable/moc-${version}.tar.bz2";
- sha256 = "486d50584c3fb0067b8c03af54e44351633a7740b18dc3b7358322051467034c";
+ url = "http://ftp.daper.net/pub/soft/moc/stable/moc-${version}.tar.bz2";
+ sha256 = "14b0g9jn12jzxsf292g64dc6frlxv99kaagsasmc8xmg80iab7nj";
};
- configurePhase = "./configure prefix=$out";
-
buildInputs = [
ncurses pkgconfig alsaLib flac libmad speex ffmpeg libvorbis
- mpc libsndfile jack2 db libmodplug timidity libid3tag libtool
+ libmpc libsndfile jack2 db libmodplug timidity libid3tag libtool
];
- meta = {
+ meta = with stdenv.lib; {
description = "An ncurses console audio player designed to be powerful and easy to use";
homepage = http://moc.daper.net/;
- license = stdenv.lib.licenses.gpl2;
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ pSub jagajaga ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/applications/audio/monkeys-audio/default.nix b/pkgs/applications/audio/monkeys-audio/default.nix
index 08aa7e017b2..d1c6ed6379a 100644
--- a/pkgs/applications/audio/monkeys-audio/default.nix
+++ b/pkgs/applications/audio/monkeys-audio/default.nix
@@ -14,6 +14,6 @@ stdenv.mkDerivation rec {
meta = with stdenv.lib; {
platforms = platforms.linux;
- maintainers = maintainers.mornfall;
+ maintainers = [ maintainers.mornfall ];
};
}
diff --git a/pkgs/applications/audio/mopidy-moped/default.nix b/pkgs/applications/audio/mopidy-moped/default.nix
index c50a1798b47..a96a5c9d898 100644
--- a/pkgs/applications/audio/mopidy-moped/default.nix
+++ b/pkgs/applications/audio/mopidy-moped/default.nix
@@ -3,11 +3,11 @@
pythonPackages.buildPythonPackage rec {
name = "mopidy-moped-${version}";
- version = "0.3.3";
+ version = "0.5.0";
src = fetchurl {
url = "https://github.com/martijnboland/moped/archive/v${version}.tar.gz";
- sha256 = "19f3asqx7wmla53nhrxzdwj6qlkjv2rcwh34jxp27bz7nkhn0ihv";
+ sha256 = "1bkx0c4yi48nxm1vzacdil9scn0ilwkbd1rgiga34p77lcg16qb2";
};
propagatedBuildInputs = [ mopidy ];
diff --git a/pkgs/applications/audio/mopidy-mopify/default.nix b/pkgs/applications/audio/mopidy-mopify/default.nix
new file mode 100644
index 00000000000..2dd4c19f0e0
--- /dev/null
+++ b/pkgs/applications/audio/mopidy-mopify/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, pythonPackages, mopidy }:
+
+pythonPackages.buildPythonPackage rec {
+ name = "mopidy-mopify-${version}";
+
+ version = "1.4.1";
+
+ src = fetchurl {
+ url = "https://github.com/dirkgroenen/mopidy-mopify/archive/${version}.tar.gz";
+ sha256 = "1i752vnkgqfps5vym63rbsh1xm141z8r68d80bi076zr6zbzdjj9";
+ };
+
+ propagatedBuildInputs = [ mopidy ];
+
+ doCheck = false;
+
+ meta = with stdenv.lib; {
+ homepage = https://github.com/dirkgroenen/mopidy-mopify;
+ description = "A mopidy webclient based on the Spotify webbased interface.";
+ license = licenses.gpl3;
+ maintainers = [ maintainers.Gonzih ];
+ };
+}
diff --git a/pkgs/applications/audio/mopidy-spotify/default.nix b/pkgs/applications/audio/mopidy-spotify/default.nix
index 6223ffb0d81..14818e60cca 100644
--- a/pkgs/applications/audio/mopidy-spotify/default.nix
+++ b/pkgs/applications/audio/mopidy-spotify/default.nix
@@ -3,11 +3,11 @@
pythonPackages.buildPythonPackage rec {
name = "mopidy-spotify-${version}";
- version = "1.2.0";
+ version = "1.3.0";
src = fetchurl {
url = "https://github.com/mopidy/mopidy-spotify/archive/v${version}.tar.gz";
- sha256 = "1fgxakylsx0nggis11v6bxfy8h3dl1n1v86liyfcj0xazb1mx69m";
+ sha256 = "0pwgg9xw86sjhv6w735fm0k81v0lv3gqlidgw90hr47hc4wajnzx";
};
propagatedBuildInputs = [ mopidy pythonPackages.pyspotify ];
@@ -16,7 +16,7 @@ pythonPackages.buildPythonPackage rec {
meta = with stdenv.lib; {
homepage = http://www.mopidy.com/;
- description = "Mopidy extension for playing music from Spotify.";
+ description = "Mopidy extension for playing music from Spotify";
license = licenses.asl20;
maintainers = [ maintainers.rickynils ];
hydraPlatforms = [];
diff --git a/pkgs/applications/audio/mopidy/default.nix b/pkgs/applications/audio/mopidy/default.nix
index bbdd1f05fde..08ccfc13302 100644
--- a/pkgs/applications/audio/mopidy/default.nix
+++ b/pkgs/applications/audio/mopidy/default.nix
@@ -5,11 +5,11 @@
pythonPackages.buildPythonPackage rec {
name = "mopidy-${version}";
- version = "0.19.3";
+ version = "1.0.0";
src = fetchurl {
url = "https://github.com/mopidy/mopidy/archive/v${version}.tar.gz";
- sha256 = "0rjq69vqak1d6fhvih259wmwp50xgr6x0x5nd0hl6hlkbbysc8dp";
+ sha256 = "15cz6mqw8ihqxhlssnbbssl3bi1xxbmq7krf3hv0zmmdj73ilsd6";
};
propagatedBuildInputs = with pythonPackages; [
@@ -28,7 +28,7 @@ pythonPackages.buildPythonPackage rec {
homepage = http://www.mopidy.com/;
description = ''
An extensible music server that plays music from local disk, Spotify,
- SoundCloud, Google Play Music, and more.
+ SoundCloud, Google Play Music, and more
'';
license = licenses.asl20;
maintainers = [ maintainers.rickynils ];
diff --git a/pkgs/applications/audio/morituri/default.nix b/pkgs/applications/audio/morituri/default.nix
new file mode 100644
index 00000000000..6498f48351d
--- /dev/null
+++ b/pkgs/applications/audio/morituri/default.nix
@@ -0,0 +1,48 @@
+{ stdenv, fetchurl, python, pythonPackages, cdparanoia, cdrdao
+, pygobject, gst_python, gst_plugins_base, gst_plugins_good
+, setuptools, utillinux, makeWrapper, substituteAll }:
+
+stdenv.mkDerivation rec {
+ name = "morituri-${version}";
+ version = "0.2.3";
+ namePrefix = "";
+
+ src = fetchurl {
+ url = "http://thomas.apestaart.org/download/morituri/${name}.tar.bz2";
+ sha256 = "1b30bs1y8azl04izsrl01gw9ys0lhzkn5afxi4p8qbiri2h4v210";
+ };
+
+ pythonPath = [
+ pygobject gst_python pythonPackages.musicbrainzngs
+ pythonPackages.pycdio pythonPackages.pyxdg setuptools
+ ];
+
+ buildInputs = [
+ python cdparanoia cdrdao utillinux makeWrapper
+ gst_plugins_base gst_plugins_good
+ ] ++ pythonPath;
+
+ patches = [
+ (substituteAll {
+ src = ./paths.patch;
+ inherit cdrdao cdparanoia python utillinux;
+ })
+ ];
+
+ # This package contains no binaries to patch or strip.
+ dontPatchELF = true;
+ dontStrip = true;
+
+ postInstall = ''
+ wrapProgram "$out/bin/rip" \
+ --prefix PYTHONPATH : "$PYTHONPATH" \
+ --prefix GST_PLUGIN_SYSTEM_PATH : "$GST_PLUGIN_SYSTEM_PATH"
+ '';
+
+ meta = with stdenv.lib; {
+ homepage = http://thomas.apestaart.org/morituri/trac/;
+ description = "A CD ripper aiming for accuracy over speed";
+ maintainers = [ maintainers.rycee ];
+ license = licenses.gpl3Plus;
+ };
+}
diff --git a/pkgs/applications/audio/morituri/paths.patch b/pkgs/applications/audio/morituri/paths.patch
new file mode 100644
index 00000000000..efabc1d200c
--- /dev/null
+++ b/pkgs/applications/audio/morituri/paths.patch
@@ -0,0 +1,91 @@
+diff -Nurp morituri-0.2.3-orig/doc/Makefile.in morituri-0.2.3/doc/Makefile.in
+--- morituri-0.2.3-orig/doc/Makefile.in 2014-12-23 12:44:46.222410092 +0100
++++ morituri-0.2.3/doc/Makefile.in 2014-12-23 12:46:49.619756940 +0100
+@@ -486,7 +486,7 @@ morituri.ics: $(top_srcdir)/morituri.doa
+ -moap doap -f $(top_srcdir)/morituri.doap ical > morituri.ics
+
+ rip.1: $(top_srcdir)/morituri/extern/python-command/scripts/help2man $(top_srcdir)/morituri
+- PYTHONPATH=$(top_srcdir) $(PYTHON) $(top_srcdir)/morituri/extern/python-command/scripts/help2man morituri.rip.main.Rip rip > rip.1
++ PYTHONPATH=$(top_srcdir):$(PYTHONPATH) $(PYTHON) $(top_srcdir)/morituri/extern/python-command/scripts/help2man morituri.rip.main.Rip rip > rip.1
+
+ clean-local:
+ @rm -rf reference
+diff -Nurp morituri-0.2.3-orig/morituri/common/program.py morituri-0.2.3/morituri/common/program.py
+--- morituri-0.2.3-orig/morituri/common/program.py 2014-12-23 12:44:46.218410048 +0100
++++ morituri-0.2.3/morituri/common/program.py 2014-12-23 12:46:49.647757245 +0100
+@@ -92,13 +92,13 @@ class Program(log.Loggable):
+ """
+ Load the given device.
+ """
+- os.system('eject -t %s' % device)
++ os.system('@utillinux@/bin/eject -t %s' % device)
+
+ def ejectDevice(self, device):
+ """
+ Eject the given device.
+ """
+- os.system('eject %s' % device)
++ os.system('@utillinux@/bin/eject %s' % device)
+
+ def unmountDevice(self, device):
+ """
+@@ -112,7 +112,7 @@ class Program(log.Loggable):
+ proc = open('/proc/mounts').read()
+ if device in proc:
+ print 'Device %s is mounted, unmounting' % device
+- os.system('umount %s' % device)
++ os.system('@utillinux@/bin/umount %s' % device)
+
+ def getFastToc(self, runner, toc_pickle, device):
+ """
+diff -Nurp morituri-0.2.3-orig/morituri/extern/python-command/scripts/help2man morituri-0.2.3/morituri/extern/python-command/scripts/help2man
+--- morituri-0.2.3-orig/morituri/extern/python-command/scripts/help2man 2014-12-23 12:44:46.206409916 +0100
++++ morituri-0.2.3/morituri/extern/python-command/scripts/help2man 2014-12-23 12:46:49.631757074 +0100
+@@ -1,4 +1,4 @@
+-#!/usr/bin/python
++#!@python@/bin/python
+
+ # -*- Mode: Python -*-
+ # vi:si:et:sw=4:sts=4:ts=4
+diff -Nurp morituri-0.2.3-orig/morituri/program/cdparanoia.py morituri-0.2.3/morituri/program/cdparanoia.py
+--- morituri-0.2.3-orig/morituri/program/cdparanoia.py 2014-12-23 12:44:46.202409873 +0100
++++ morituri-0.2.3/morituri/program/cdparanoia.py 2014-12-23 12:46:49.659757376 +0100
+@@ -278,7 +278,7 @@ class ReadTrackTask(log.Loggable, task.T
+ stopTrack, stopOffset)
+
+ bufsize = 1024
+- argv = ["cdparanoia", "--stderr-progress",
++ argv = ["@cdparanoia@/bin/cdparanoia", "--stderr-progress",
+ "--sample-offset=%d" % self._offset, ]
+ if self._device:
+ argv.extend(["--force-cdrom-device", self._device, ])
+@@ -551,7 +551,7 @@ _VERSION_RE = re.compile(
+
+ def getCdParanoiaVersion():
+ getter = common.VersionGetter('cdparanoia',
+- ["cdparanoia", "-V"],
++ ["@cdparanoia@/bin/cdparanoia", "-V"],
+ _VERSION_RE,
+ "%(version)s %(release)s")
+
+diff -Nurp morituri-0.2.3-orig/morituri/program/cdrdao.py morituri-0.2.3/morituri/program/cdrdao.py
+--- morituri-0.2.3-orig/morituri/program/cdrdao.py 2014-12-23 12:44:46.202409873 +0100
++++ morituri-0.2.3/morituri/program/cdrdao.py 2014-12-23 12:46:49.667757463 +0100
+@@ -257,7 +257,7 @@ class CDRDAOTask(ctask.PopenTask):
+
+ def start(self, runner):
+ self.debug('Starting cdrdao with options %r', self.options)
+- self.command = ['cdrdao', ] + self.options
++ self.command = ['@cdrdao@/bin/cdrdao', ] + self.options
+
+ ctask.PopenTask.start(self, runner)
+
+@@ -515,7 +515,7 @@ _VERSION_RE = re.compile(
+
+ def getCDRDAOVersion():
+ getter = common.VersionGetter('cdrdao',
+- ["cdrdao"],
++ ["@cdrdao@/bin/cdrdao"],
+ _VERSION_RE,
+ "%(version)s")
+
diff --git a/pkgs/applications/audio/mp3gain/default.nix b/pkgs/applications/audio/mp3gain/default.nix
new file mode 100644
index 00000000000..3fef8398e9c
--- /dev/null
+++ b/pkgs/applications/audio/mp3gain/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchurl, unzip }:
+
+stdenv.mkDerivation {
+ name = "mp3gain-1.5.2";
+ src = fetchurl {
+ url = "http://downloads.sourceforge.net/mp3gain/mp3gain-1_5_2-src.zip";
+ sha256 = "1jkgry59m8cnnfq05b9y1h4x4wpy3iq8j68slb9qffwa3ajcgbfv";
+ };
+
+ buildInputs = [ unzip ];
+
+ sourceRoot = ".";
+
+ buildFlags = [ "OSTYPE=linux" ];
+
+ installPhase = ''
+ install -vD mp3gain "$out/bin/mp3gain"
+ '';
+
+ meta = {
+ description = "Lossless mp3 normalizer with statistical analysis";
+ homepage = http://mp3gain.sourceforge.net/;
+ license = stdenv.lib.licenses.lgpl21;
+ platforms = stdenv.lib.platforms.linux;
+ maintainers = [ stdenv.lib.maintainers.devhell ];
+ };
+}
diff --git a/pkgs/applications/audio/mp3info/default.nix b/pkgs/applications/audio/mp3info/default.nix
index ede31ac9beb..e4c45c613ee 100644
--- a/pkgs/applications/audio/mp3info/default.nix
+++ b/pkgs/applications/audio/mp3info/default.nix
@@ -36,7 +36,7 @@ stdenv.mkDerivation rec {
license = stdenv.lib.licenses.gpl2Plus;
- maintainers = [ stdenv.lib.maintainers.ludo ];
+ maintainers = [ ];
platforms = stdenv.lib.platforms.unix;
};
}
diff --git a/pkgs/applications/audio/mp3splt/default.nix b/pkgs/applications/audio/mp3splt/default.nix
index b1970a998d5..08d91498cc0 100644
--- a/pkgs/applications/audio/mp3splt/default.nix
+++ b/pkgs/applications/audio/mp3splt/default.nix
@@ -13,7 +13,7 @@ stdenv.mkDerivation rec {
meta = {
description = "utility to split mp3, ogg vorbis and FLAC files without decoding";
homepage = http://sourceforge.net/projects/mp3splt/;
- license = "GPLv2";
+ license = stdenv.lib.licenses.gpl2;
maintainers = [ stdenv.lib.maintainers.bosu ];
platforms = stdenv.lib.platforms.unix;
};
diff --git a/pkgs/applications/audio/mpc/default.nix b/pkgs/applications/audio/mpc/default.nix
old mode 100755
new mode 100644
index 54ae5476efd..9224e21185b
--- a/pkgs/applications/audio/mpc/default.nix
+++ b/pkgs/applications/audio/mpc/default.nix
@@ -1,16 +1,16 @@
{ stdenv, fetchurl, mpd_clientlib }:
stdenv.mkDerivation rec {
- version = "0.25";
+ version = "0.26";
name = "mpc-${version}";
src = fetchurl {
url = "http://www.musicpd.org/download/mpc/0/${name}.tar.xz";
- sha256 = "095gmik5vrnab5a1g92qiznn48w7499fr0gldp3s6xd26kvs9kvh";
+ sha256 = "0hp2qv6w2v902dhrmck5hg32s1ai6xiv9n61a3n6prfcfdqmywr0";
};
-
- buildInputs = [ mpd_clientlib ];
-
+
+ buildInputs = [ mpd_clientlib ];
+
preConfigure =
''
export LIBMPDCLIENT_LIBS=${mpd_clientlib}/lib/libmpdclient.so.${mpd_clientlib.majorVersion}.0.${mpd_clientlib.minorVersion}
diff --git a/pkgs/applications/audio/mpg321/default.nix b/pkgs/applications/audio/mpg321/default.nix
index 939c9f79e4d..489831dc464 100644
--- a/pkgs/applications/audio/mpg321/default.nix
+++ b/pkgs/applications/audio/mpg321/default.nix
@@ -1,20 +1,28 @@
-{stdenv, fetchurl, libao, libmad, libid3tag, zlib}:
+{stdenv, fetchurl, libao, libmad, libid3tag, zlib, alsaLib}:
stdenv.mkDerivation rec {
- name = "mpg321-0.2.13-2";
+ name = "mpg321-${version}";
+ version = "0.3.2";
src = fetchurl {
- url = "mirror://sourceforge/mpg321/0.2.13/${name}.tar.gz";
- sha256 = "0zx9xyr97frlyrwyk2msm9h1sn2b84vqaxcy5drbzcd2n585lwlx";
+ url = "mirror://sourceforge/mpg321/${version}/mpg321_${version}.orig.tar.gz";
+ sha256 = "0ki8mh76bbmdh77qsiw682dvi8y468yhbdabqwg05igmwc1wqvq5";
};
- buildInputs = [libao libid3tag libmad zlib];
+ configureFlags = [
+ ("--enable-alsa=" + (if stdenv.isLinux then "yes" else "no"))
+ ];
- meta = {
+ buildInputs = [libao libid3tag libmad zlib]
+ ++ stdenv.lib.optional stdenv.isLinux alsaLib;
+
+ installTargets = "install install-man";
+
+ meta = with stdenv.lib; {
description = "Command-line MP3 player";
homepage = http://mpg321.sourceforge.net/;
- license = stdenv.lib.licenses.gpl2;
- maintainers = [ ];
- platforms = stdenv.lib.platforms.gnu;
+ license = licenses.gpl2;
+ maintainers = [ maintainers.rycee ];
+ platforms = platforms.gnu;
};
}
diff --git a/pkgs/applications/audio/musescore/default.nix b/pkgs/applications/audio/musescore/default.nix
new file mode 100644
index 00000000000..a0bb8789658
--- /dev/null
+++ b/pkgs/applications/audio/musescore/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, fetchurl, makeWrapper, cmake, qt4, pkgconfig, alsaLib, portaudio, jack2, libsndfile}:
+
+stdenv.mkDerivation rec {
+ name = "musescore-1.3";
+
+ src = fetchurl {
+ url = "http://ftp.osuosl.org/pub/musescore/releases/MuseScore-1.3/mscore-1.3.tar.bz2";
+ sha256 = "a0b60cc892ac0266c58fc6392be72c0a21c3aa7fd0b6e4f1dddad1c8b36be683";
+ };
+
+ buildInputs = [ makeWrapper cmake qt4 pkgconfig alsaLib portaudio jack2 libsndfile ];
+
+ configurePhase = ''
+ cd mscore;
+ mkdir build;
+ cd build;
+ cmake -DCMAKE_INSTALL_PREFIX=$out -DQT_PLUGINS_DIR=$out/lib/qt4/plugins -DCMAKE_BUILD_TYPE=Release ..'';
+
+ preBuild = ''make lrelease;'';
+
+ postInstall = ''
+ wrapProgram $out/bin/mscore --prefix QT_PLUGIN_PATH : $out/lib/qt4/plugins
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Qt-based score editor";
+ homepage = http://musescore.org/;
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ maintainers = [ stdenv.lib.maintainers.vandenoever ];
+ repositories.git = https://github.com/musescore/MuseScore;
+ };
+}
diff --git a/pkgs/applications/audio/ncmpc/default.nix b/pkgs/applications/audio/ncmpc/default.nix
old mode 100755
new mode 100644
index 94fa50a8883..b5f84f536d0
--- a/pkgs/applications/audio/ncmpc/default.nix
+++ b/pkgs/applications/audio/ncmpc/default.nix
@@ -1,12 +1,12 @@
{ stdenv, fetchurl, pkgconfig, glib, ncurses, mpd_clientlib, libintlOrEmpty }:
stdenv.mkDerivation rec {
- version = "0.23";
+ version = "0.24";
name = "ncmpc-${version}";
src = fetchurl {
url = "http://www.musicpd.org/download/ncmpc/0/ncmpc-${version}.tar.xz";
- sha256 = "d7b30cefaf5c74a5d8ab18ab8275e0102ae12e8ee6d6f8144f8e4cc9a97b5de4";
+ sha256 = "1sf3nirs3mcx0r5i7acm9bsvzqzlh730m0yjg6jcyj8ln6r7cvqf";
};
buildInputs = [ pkgconfig glib ncurses mpd_clientlib ]
@@ -14,6 +14,11 @@ stdenv.mkDerivation rec {
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isDarwin "-lintl";
+ configureFlags = [
+ "--enable-colors"
+ "--enable-lyrics-screen"
+ ];
+
meta = with stdenv.lib; {
description = "Curses-based interface for MPD (music player daemon)";
homepage = http://www.musicpd.org/clients/ncmpc/;
diff --git a/pkgs/applications/audio/ncmpcpp/default.nix b/pkgs/applications/audio/ncmpcpp/default.nix
index 186c5265433..bf437584559 100644
--- a/pkgs/applications/audio/ncmpcpp/default.nix
+++ b/pkgs/applications/audio/ncmpcpp/default.nix
@@ -1,24 +1,45 @@
-{ stdenv, fetchurl, ncurses, curl, taglib, fftw, mpd_clientlib, pkgconfig
-, libiconvOrEmpty }:
+{ stdenv, fetchurl, boost, mpd_clientlib, ncurses, pkgconfig, readline
+, libiconv
+, outputsSupport ? false # outputs screen
+, visualizerSupport ? false, fftw ? null # visualizer screen
+, clockSupport ? false # clock screen
+, unicodeSupport ? true # utf8 support
+, curlSupport ? true, curl ? null # allow fetching lyrics from the internet
+, taglibSupport ? true, taglib ? null # tag editor
+}:
+assert visualizerSupport -> (fftw != null);
+assert curlSupport -> (curl != null);
+assert taglibSupport -> (taglib != null);
+
+with stdenv.lib;
stdenv.mkDerivation rec {
- version = "0.5.10";
name = "ncmpcpp-${version}";
+ version = "0.6.3";
src = fetchurl {
- url = "http://ncmpcpp.rybczak.net/stable/ncmpcpp-${version}.tar.bz2";
- sha256 = "ff6d5376a2d9caba6f5bb78e68af77cefbdb2f04cd256f738e39f8ac9a79a4a8";
+ url = "http://ncmpcpp.rybczak.net/stable/${name}.tar.bz2";
+ sha256 = "00r2f7psd2jym2lxf3q3lz2lskz7091pz9glnxqam2bznwnlyxyp";
};
- buildInputs = [ ncurses curl taglib fftw mpd_clientlib pkgconfig ]
- ++ libiconvOrEmpty;
+ configureFlags = [ "BOOST_LIB_SUFFIX=" ]
+ ++ optional outputsSupport "--enable-outputs"
+ ++ optional visualizerSupport "--enable-visualizer --with-fftw"
+ ++ optional clockSupport "--enable-clock"
+ ++ optional unicodeSupport "--enable-unicode"
+ ++ optional curlSupport "--with-curl"
+ ++ optional taglibSupport "--with-taglib";
- meta = with stdenv.lib; {
- description = "Curses-based interface for MPD (music player daemon)";
- homepage = http://unkart.ovh.org/ncmpcpp/;
+ buildInputs = [ boost mpd_clientlib ncurses pkgconfig readline libiconv ]
+ ++ optional curlSupport curl
+ ++ optional visualizerSupport fftw
+ ++ optional taglibSupport taglib;
+
+ meta = {
+ description = "A featureful ncurses based MPD client inspired by ncmpc";
+ homepage = http://ncmpcpp.rybczak.net/;
license = licenses.gpl2Plus;
- maintainers = with maintainers; [ lovek323 mornfall ];
+ maintainers = with maintainers; [ lovek323 mornfall koral ];
platforms = platforms.all;
};
}
-
diff --git a/pkgs/applications/audio/nova-filters/default.nix b/pkgs/applications/audio/nova-filters/default.nix
new file mode 100644
index 00000000000..f49f756ce3a
--- /dev/null
+++ b/pkgs/applications/audio/nova-filters/default.nix
@@ -0,0 +1,35 @@
+{stdenv, fetchurl, scons, boost, ladspaH, pkgconfig }:
+
+stdenv.mkDerivation rec {
+ version = "0.2-2";
+ name = "nova-filters-${version}";
+
+ src = fetchurl {
+ url = http://klingt.org/~tim/nova-filters/nova-filters_0.2-2.tar.gz;
+ sha256 = "16064vvl2w5lz4xi3lyjk4xx7fphwsxc14ajykvndiz170q32s6i";
+ };
+
+ buildInputs = [ scons boost ladspaH pkgconfig ];
+
+ patchPhase = ''
+ # remove TERM:
+ sed -i -e '4d' SConstruct
+ sed -i "s@mfpmath=sse@mfpmath=sse -I ${boost.dev}/include@g" SConstruct
+ sed -i "s@ladspa.h@${ladspaH}/include/ladspa.h@g" filters.cpp
+ sed -i "s/= check/= detail::filter_base::check/" nova/source/dsp/filter.hpp
+ '';
+
+ buildPhase = ''
+ scons
+ '';
+
+ installPhase = ''
+ scons $sconsFlags "prefix=$out" install
+ '';
+
+ meta = {
+ homepage = http://klingt.org/~tim/nova-filters/;
+ description = "LADSPA plugins based on filters of nova";
+ license = stdenv.lib.licenses.gpl2Plus;
+ };
+}
diff --git a/pkgs/applications/audio/opus-tools/default.nix b/pkgs/applications/audio/opus-tools/default.nix
index 791763ced36..fb32674d3b4 100644
--- a/pkgs/applications/audio/opus-tools/default.nix
+++ b/pkgs/applications/audio/opus-tools/default.nix
@@ -1,10 +1,10 @@
{stdenv, fetchurl, libogg, libao, pkgconfig, libopus, flac}:
stdenv.mkDerivation rec {
- name = "opus-tools-0.1.8";
+ name = "opus-tools-0.1.9";
src = fetchurl {
url = "http://downloads.xiph.org/releases/opus/${name}.tar.gz";
- sha256 = "1xm2lhdz92n9zmk496lyagisyzja46kx8q340vay9i51krbqiqg4";
+ sha256 = "0fk4nknvl111k89j5yckmyrh6b2wvgyhrqfncp7rig3zikbkv1xi";
};
buildInputs = [ libogg libao pkgconfig libopus flac ];
@@ -12,6 +12,7 @@ stdenv.mkDerivation rec {
meta = {
description = "Tools to work with opus encoded audio streams";
homepage = http://www.opus-codec.org/;
- license = "BSD";
+ license = stdenv.lib.licenses.bsd2;
+ maintainers = with stdenv.lib.maintainers; [ fuuzetsu ];
};
}
diff --git a/pkgs/applications/audio/opusfile/default.nix b/pkgs/applications/audio/opusfile/default.nix
index 50df35b974f..314ecc95c3f 100644
--- a/pkgs/applications/audio/opusfile/default.nix
+++ b/pkgs/applications/audio/opusfile/default.nix
@@ -1,10 +1,10 @@
{stdenv, fetchurl, pkgconfig, openssl, libogg, libopus}:
stdenv.mkDerivation rec {
- name = "opusfile-0.4";
+ name = "opusfile-0.6";
src = fetchurl {
url = "http://downloads.xiph.org/releases/opus/${name}.tar.gz";
- sha256 = "0h4iwyqgid0cibqwzckz3r94qfp09099nk1cx5nz6i3cf08yldlq";
+ sha256 = "19iys2kld75k0210b807i4illrdmj3cmmnrgxlc9y4vf6mxp2a14";
};
buildInputs = [ pkgconfig openssl libogg libopus ];
@@ -12,6 +12,7 @@ stdenv.mkDerivation rec {
meta = {
description = "High-level API for decoding and seeking in .opus files";
homepage = http://www.opus-codec.org/;
- license = "BSD";
+ license = stdenv.lib.licenses.bsd3;
+ maintainers = with stdenv.lib.maintainers; [ fuuzetsu ];
};
}
diff --git a/pkgs/applications/audio/paprefs/default.nix b/pkgs/applications/audio/paprefs/default.nix
new file mode 100644
index 00000000000..f05c4068a60
--- /dev/null
+++ b/pkgs/applications/audio/paprefs/default.nix
@@ -0,0 +1,33 @@
+{ fetchurl, stdenv, pkgconfig, pulseaudio, gtkmm, libglademm
+, dbus_glib, gconfmm, intltool }:
+
+stdenv.mkDerivation rec {
+ name = "paprefs-0.9.10";
+
+ src = fetchurl {
+ url = "http://freedesktop.org/software/pulseaudio/paprefs/${name}.tar.xz";
+ sha256 = "1c5b3sb881szavly220q31g7rvpn94wr7ywlk00hqb9zaikml716";
+ };
+
+ buildInputs = [ pulseaudio gtkmm libglademm dbus_glib gconfmm ];
+
+ nativeBuildInputs = [ pkgconfig intltool ];
+
+ configureFlags = [ "--disable-lynx" ];
+
+ meta = with stdenv.lib; {
+ description = "PulseAudio Preferences";
+
+ longDescription = ''
+ PulseAudio Preferences (paprefs) is a simple GTK based configuration
+ dialog for the PulseAudio sound server.
+ '';
+
+ homepage = http://freedesktop.org/software/pulseaudio/paprefs/ ;
+
+ license = licenses.gpl2Plus;
+
+ maintainers = [ maintainers.abbradar ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pavucontrol/default.nix b/pkgs/applications/audio/pavucontrol/default.nix
index ca08624e98f..8e4c31302e2 100644
--- a/pkgs/applications/audio/pavucontrol/default.nix
+++ b/pkgs/applications/audio/pavucontrol/default.nix
@@ -1,20 +1,27 @@
-{ fetchurl, stdenv, pkgconfig, pulseaudio, gtkmm3
-, libcanberra_gtk3, intltool, gettext }:
+{ fetchurl, stdenv, pkgconfig, intltool, pulseaudio, gtkmm3
+, libcanberra_gtk3, makeWrapper, gnome3 }:
stdenv.mkDerivation rec {
- name = "pavucontrol-2.0";
+ name = "pavucontrol-3.0";
src = fetchurl {
url = "http://freedesktop.org/software/pulseaudio/pavucontrol/${name}.tar.xz";
- sha256 = "02s775m1531sshwlbvfddk3pz8zjmwkv1sgzggn386ja3gc9vwi2";
+ sha256 = "14486c6lmmirkhscbfygz114f6yzf97h35n3h3pdr27w4mdfmlmk";
};
- buildInputs = [ pkgconfig pulseaudio gtkmm3 libcanberra_gtk3
- intltool gettext ];
+ preFixup = ''
+ wrapProgram "$out/bin/pavucontrol" \
+ --prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS"
+ '';
- configureFlags = "--disable-lynx";
+ buildInputs = [ pulseaudio gtkmm3 libcanberra_gtk3 makeWrapper
+ gnome3.gnome_icon_theme ];
- meta = {
+ nativeBuildInputs = [ pkgconfig intltool ];
+
+ configureFlags = [ "--disable-lynx" ];
+
+ meta = with stdenv.lib; {
description = "PulseAudio Volume Control";
longDescription = ''
@@ -27,7 +34,7 @@ stdenv.mkDerivation rec {
license = stdenv.lib.licenses.gpl2Plus;
- maintainers = [ ];
- platforms = stdenv.lib.platforms.gnu; # arbitrary choice
+ maintainers = [ maintainers.abbradar ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/applications/audio/pd-plugins/cyclone/default.nix b/pkgs/applications/audio/pd-plugins/cyclone/default.nix
new file mode 100644
index 00000000000..b90c6a0ea36
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/cyclone/default.nix
@@ -0,0 +1,37 @@
+{ stdenv, fetchurl, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "cyclone-${version}";
+ version = "0.1-alpha55";
+
+ src = fetchurl {
+ url = "http://downloads.sourceforge.net/project/pure-data/libraries/cyclone/${name}.tar.gz";
+ sha256 = "1yys9xrlz09xgnqk2gqdl8vw6xj6l9d7km2lkihidgjql0jx5b5i";
+ };
+
+ buildInputs = [ puredata ];
+
+ patchPhase = ''
+ for file in `grep -r -l g_canvas.h`
+ do
+ sed -i 's|#include "g_canvas.h"|#include "${puredata}/include/pd/g_canvas.h"|g' $file
+ done
+ for file in `grep -r -l m_imp.h`
+ do
+ sed -i 's|#include "m_imp.h"|#include "${puredata}/include/pd/m_imp.h"|g' $file
+ done
+ '';
+
+ installPhase = ''
+ mkdir -p $out/cyclone
+ cp -r bin/* $out/cyclone
+ '';
+
+ meta = {
+ description = "A library of PureData classes, bringing some level of compatibility between Max/MSP and Pd environments";
+ homepage = http://puredata.info/downloads/cyclone;
+ license = stdenv.lib.licenses.tcltk;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/helmholtz/default.nix b/pkgs/applications/audio/pd-plugins/helmholtz/default.nix
new file mode 100644
index 00000000000..9046ec0a87f
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/helmholtz/default.nix
@@ -0,0 +1,42 @@
+{ stdenv, fetchurl, unzip, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "helmholtz";
+
+ src = fetchurl {
+ url = "http://www.katjaas.nl/helmholtz/helmholtz~.zip";
+ name = "helmholtz.zip";
+ sha256 = "0h1fj7lmvq9j6rmw33rb8k0byxb898bi2xhcwkqalb84avhywgvs";
+ };
+
+ buildInputs = [ unzip puredata ];
+
+ unpackPhase = ''
+ unzip $src
+ mv helmholtz~/src/helmholtz\~.cpp .
+ mv helmholtz~/src/Helmholtz.cpp .
+ mv helmholtz~/src/include/ .
+ mv helmholtz~/src/Makefile .
+ rm -rf helmholtz~/src/
+ rm helmholtz~/helmholtz~.pd_darwin
+ rm helmholtz~/helmholtz~.dll
+ rm -rf __MACOSX
+ '';
+
+ patchPhase = ''
+ sed -i "s@current: pd_darwin@current: pd_linux@g" Makefile
+ sed -i "s@-Wl@@g" Makefile
+ '';
+
+ installPhase = ''
+ cp -r helmholtz~/ $out/
+ '';
+
+ meta = {
+ description = "Time domain pitch tracker for Pure Data";
+ homepage = http://www.katjaas.nl/helmholtz/helmholtz.html;
+ license = stdenv.lib.licenses.bsd3;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/maxlib/default.nix b/pkgs/applications/audio/pd-plugins/maxlib/default.nix
new file mode 100644
index 00000000000..dc4d0375961
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/maxlib/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, fetchurl, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "maxlib-${version}";
+ version = "1.5.5";
+
+ src = fetchurl {
+ url = "http://downloads.sourceforge.net/project/pure-data/libraries/maxlib/${name}.tar.gz";
+ sha256 = "0vxl9s815dnay5r0067rxsfh8f6jbk61f0nxrydzjydfycza7p1w";
+ };
+
+ buildInputs = [ puredata ];
+
+ patchPhase = ''
+ for i in ${puredata}/include/pd/*; do
+ ln -s $i .
+ done
+ sed -i "s@/usr@$out@g" Makefile
+ '';
+
+ postInstall = ''
+ mv $out/local/lib/pd-externals/maxlib/ $out
+ rm -rf $out/local/
+ '';
+
+ meta = {
+ description = "A library of non-tilde externals for puredata, by Miller Puckette";
+ homepage = http://puredata.info/downloads/maxlib;
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/mrpeach/default.nix b/pkgs/applications/audio/pd-plugins/mrpeach/default.nix
new file mode 100644
index 00000000000..5f76b208e14
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/mrpeach/default.nix
@@ -0,0 +1,60 @@
+{ stdenv, fetchurl, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "mrpeach-${version}";
+ version = "1.1";
+
+ # this was to only usable url I could find:
+ # - The main url changes hash: http://pure-data.cvs.sourceforge.net/viewvc/pure-data/externals/mrpeach/?view=tar
+ # - There are lot's of places where this SW is available as part of a big pkg: pd-extended, pd-l2ork
+ # - It's just 211K
+
+ src = fetchurl {
+ url = "http://slackonly.com/pub/korgie/sources/pd_mrpeach-2011.10.21.tar.gz";
+ sha256 = "12jqba3jsdrk20ib9wc2wiivki88ypcd4mkzgsri9siywbbz9w8x";
+ };
+
+ buildInputs = [puredata ];
+
+ patchPhase = ''
+ for D in net osc
+ do
+ sed -i "s@prefix = /usr/local@prefix = $out@g" $D/Makefile
+ for i in ${puredata}/include/pd/*; do
+ ln -s $i $D/
+ done
+ done
+ '';
+
+ buildPhase = ''
+ for D in net osc
+ do
+ cd $D
+ make
+ cd ..
+ done
+ '';
+
+ installPhase = ''
+ for D in net osc
+ do
+ cd $D
+ make install
+ cd ..
+ done
+ '';
+
+ fixupPhase = ''
+ mv $out/lib/pd-externals/net $out
+ mv $out/lib/pd-externals/osc $out
+ rm -rf $out/lib
+ '';
+
+ meta = {
+ description = "A collection of Pd objectclasses for OSC-messages";
+ homepage = http://puredata.info/downloads/osc;
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/puremapping/default.nix b/pkgs/applications/audio/pd-plugins/puremapping/default.nix
new file mode 100644
index 00000000000..fc7fc5ee3d0
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/puremapping/default.nix
@@ -0,0 +1,30 @@
+{ stdenv, fetchurl, unzip, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "puremapping";
+
+ src = fetchurl {
+ url = "http://www.chnry.net/ch/IMG/zip/puremapping-libdir-generic.zip";
+ name = "puremapping";
+ sha256 = "1ygzxsfj3rnzjkpmgi4wch810q8s5vm1gdam6a938hbbvamafgvc";
+ };
+
+ buildInputs = [ unzip puredata ];
+
+ unpackPhase = ''
+ unzip $src
+ '';
+
+ installPhase = ''
+ mkdir -p $out/puremapping
+ mv puremapping/ $out
+ '';
+
+ meta = {
+ description = "Set of externals to facilitate the use of sensors within Pure Data and to create complex relations between input and output of a dynamic system";
+ homepage = http://www.chnry.net/ch/?090-Pure-Mapping&lang=en;
+ license = stdenv.lib.licenses.gpl1;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/timbreid/default.nix b/pkgs/applications/audio/pd-plugins/timbreid/default.nix
new file mode 100644
index 00000000000..f8a25256bb0
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/timbreid/default.nix
@@ -0,0 +1,35 @@
+{ stdenv, fetchurl, unzip, puredata }:
+
+stdenv.mkDerivation rec {
+ version = "0.6.0";
+ name = "timbreid-${version}";
+
+ src = fetchurl {
+ url = "http://williambrent.conflations.com/pd/timbreID-${version}-src.zip";
+ sha256 = "02rnkb0vpjxrr60c3hryv7zhyjpci2mi9dk27kjxpj5zp26gjk0p";
+ };
+
+ buildInputs = [ unzip puredata ];
+
+ unpackPhase = ''
+ unzip $src
+ mv timbreID-0.6.0-src/tID/* .
+ rm -rf timbreID-0.6.0-src/tID/
+ rm -rf timbreID-0.6.0-src/INSTALL.txt
+ '';
+
+ installPhase = ''
+ mkdir -p $out/
+ cp -r *.pd $out/
+ cp -r *.pd_linux $out/
+ cp -r *.wav $out/
+ '';
+
+ meta = {
+ description = "A collection of audio feature analysis externals for puredata";
+ homepage = http://williambrent.conflations.com/pages/research.html;
+ license = stdenv.lib.licenses.gpl3;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/pd-plugins/zexy/default.nix b/pkgs/applications/audio/pd-plugins/zexy/default.nix
new file mode 100644
index 00000000000..68996e9e6e4
--- /dev/null
+++ b/pkgs/applications/audio/pd-plugins/zexy/default.nix
@@ -0,0 +1,36 @@
+{ stdenv, fetchurl, autoconf, automake, puredata }:
+
+stdenv.mkDerivation rec {
+ name = "zexy-${version}";
+ version = "2.2.4";
+
+ src = fetchurl {
+ url = "http://puredata.info/downloads/zexy/releases/${version}/${name}.tar.gz";
+ sha256 = "1xpgl82c2lc6zfswjsa7z10yhv5jb7a4znzh3nc7ffrzm1z8vylp";
+ };
+
+ buildInputs = [ autoconf automake puredata ];
+
+ patchPhase = ''
+ cd src/
+ for i in ${puredata}/include/pd/*; do
+ ln -s $i .
+ done
+ patchShebangs
+ ./bootstrap.sh
+ ./configure --enable-lpt=no --prefix=$out
+ '';
+
+ postInstall = ''
+ mv $out/lib/pd/extra/zexy $out
+ rm -rf $out/lib
+ '';
+
+ meta = {
+ description = "The swiss army knife for puredata";
+ homepage = http://puredata.info/downloads/zexy;
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/petrifoo/default.nix b/pkgs/applications/audio/petrifoo/default.nix
index 152ee442761..197a0aa1bbe 100644
--- a/pkgs/applications/audio/petrifoo/default.nix
+++ b/pkgs/applications/audio/petrifoo/default.nix
@@ -1,14 +1,14 @@
-{ stdenv, fetchgit, alsaLib, cmake, gtk, jack2, libgnomecanvas
+{ stdenv, fetchurl, alsaLib, cmake, gtk, jack2, libgnomecanvas
, libpthreadstubs, libsamplerate, libsndfile, libtool, libxml2
, pkgconfig }:
stdenv.mkDerivation rec {
- name = "petri-foo";
+ name = "petri-foo-${version}";
+ version = "0.1.87";
- src = fetchgit {
- url = https://github.com/licnep/Petri-Foo.git;
- rev = "eef3b6efebe842d2fa18ed32b881fea4562b84e0";
- sha256 = "a20c3f1a633500a65c099c528c7dc2405daa60738b64d881bb8f2036ae59913c";
+ src = fetchurl {
+ url = "mirror://sourceforge/petri-foo/${name}.tar.bz2";
+ sha256 = "0b25iicgn8c42487fdw32ycfrll1pm2zjgy5djvgw6mfcaa4gizh";
};
buildInputs =
@@ -16,8 +16,6 @@ stdenv.mkDerivation rec {
libsamplerate libsndfile libtool libxml2 pkgconfig
];
- dontUseCmakeBuildDir=true;
-
meta = with stdenv.lib; {
description = "MIDI controllable audio sampler";
longDescription = "a fork of Specimen";
diff --git a/pkgs/applications/audio/pianobar/default.nix b/pkgs/applications/audio/pianobar/default.nix
index a9f4b02fa08..3e7bcb9d912 100644
--- a/pkgs/applications/audio/pianobar/default.nix
+++ b/pkgs/applications/audio/pianobar/default.nix
@@ -1,15 +1,15 @@
-{ fetchurl, stdenv, pkgconfig, libao, faad2, libmad, readline, json_c, libgcrypt, gnutls }:
+{ fetchurl, stdenv, pkgconfig, libao, readline, json_c, libgcrypt, gnutls, libav }:
stdenv.mkDerivation rec {
- name = "pianobar-2013.05.19";
+ name = "pianobar-2014.09.28";
src = fetchurl {
url = "http://6xq.net/projects/pianobar/${name}.tar.bz2";
- sha256 = "cf88e82663d2b0aa4d73e761506eac4f3e7bc789b57d92377acd994d785e1046";
+ sha256 = "6bd10218ad5d68c4c761e02c729627d2581b4a6db559190e7e52dc5df177e68f";
};
buildInputs = [
- pkgconfig libao faad2 libmad json_c libgcrypt gnutls
+ pkgconfig libao json_c libgcrypt gnutls libav
];
makeFlags="PREFIX=$(out)";
@@ -17,10 +17,13 @@ stdenv.mkDerivation rec {
CC = "gcc";
CFLAGS = "-std=c99";
+ configurePhase = "export CC=${CC}";
+
meta = {
description = "A console front-end for Pandora.com";
homepage = "http://6xq.net/projects/pianobar/";
platforms = stdenv.lib.platforms.linux;
- license = stdenv.lib.licenses.unfree;
+ license = stdenv.lib.licenses.mit; # expat version
+ maintainers = stdenv.lib.maintainers.eduarrrd;
};
}
diff --git a/pkgs/applications/audio/picard/default.nix b/pkgs/applications/audio/picard/default.nix
index 235a81a6a32..3d0114352a1 100644
--- a/pkgs/applications/audio/picard/default.nix
+++ b/pkgs/applications/audio/picard/default.nix
@@ -1,26 +1,18 @@
-{ stdenv, fetchurl, pythonPackages, gettext, pyqt4
-, pkgconfig, libdiscid, libofa, ffmpeg, chromaprint
+{ stdenv, buildPythonPackage, fetchurl, gettext
+, pkgconfig, libofa, ffmpeg, chromaprint
+, pyqt4, mutagen, python-libdiscid
}:
-pythonPackages.buildPythonPackage rec {
+let version = "1.3.2"; in
+buildPythonPackage {
name = "picard-${version}";
namePrefix = "";
- version = "1.2";
src = fetchurl {
- url = "http://ftp.musicbrainz.org/pub/musicbrainz/picard/${name}.tar.gz";
- sha256 = "0sbsf8hzxhxcnnjqvsd6mc23lmk7w33nln0f3w72f89mjgs6pxm6";
+ url = "http://ftp.musicbrainz.org/pub/musicbrainz/picard/picard-${version}.tar.gz";
+ sha256 = "0821xb7gyg0rhch8s3qkzmak90wjpcxkv9a364yv6bmqc12j6a77";
};
- postPatch = let
- discid = "${libdiscid}/lib/libdiscid.so.0";
- fpr = "${chromaprint}/bin/fpcalc";
- in ''
- substituteInPlace picard/disc.py --replace libdiscid.so.0 ${discid}
- substituteInPlace picard/const.py \
- --replace "FPCALC_NAMES = [" "FPCALC_NAMES = ['${fpr}',"
- '';
-
buildInputs = [
pkgconfig
ffmpeg
@@ -29,19 +21,11 @@ pythonPackages.buildPythonPackage rec {
];
propagatedBuildInputs = [
- pythonPackages.mutagen
pyqt4
- libdiscid
+ mutagen
+ python-libdiscid
];
- configurePhase = ''
- python setup.py config
- '';
-
- buildPhase = ''
- python setup.py build
- '';
-
installPhase = ''
python setup.py install --prefix="$out"
'';
diff --git a/pkgs/applications/audio/praat/default.nix b/pkgs/applications/audio/praat/default.nix
index 86c68d087b7..354a3e43616 100644
--- a/pkgs/applications/audio/praat/default.nix
+++ b/pkgs/applications/audio/praat/default.nix
@@ -1,11 +1,12 @@
{ stdenv, fetchurl, alsaLib, gtk, pkgconfig }:
+let version = "5401"; in
stdenv.mkDerivation {
- name = "praat-5365";
+ name = "praat-${version}";
src = fetchurl {
- url = http://www.fon.hum.uva.nl/praat/praat5365_sources.tar.gz;
- sha256 = "1w3mcq0mipx88i7ckhvzhmdj0p67nhppnn7kbkp21d01yyyz5rgq";
+ url = "http://www.fon.hum.uva.nl/praat/praat${version}_sources.tar.gz";
+ sha256 = "1hx0simc0hp5w5scyaiw8h8lrpafra4h1zy1jn1kzb0299yd06n3";
};
configurePhase = ''
diff --git a/pkgs/applications/audio/puredata/wrapper.nix b/pkgs/applications/audio/puredata/wrapper.nix
new file mode 100644
index 00000000000..0a30037b226
--- /dev/null
+++ b/pkgs/applications/audio/puredata/wrapper.nix
@@ -0,0 +1,23 @@
+{ stdenv, buildEnv, puredata, makeWrapper, plugins }:
+
+let
+puredataFlags = map (x: "-path ${x}/") plugins;
+drv = buildEnv {
+ name = "puredata-with-plugins-" + (builtins.parseDrvName puredata.name).version;
+
+ paths = [ puredata ] ++ plugins;
+
+ postBuild = ''
+ # TODO: This could be avoided if buildEnv could be forced to create all directories
+ if [ -L $out/bin ]; then
+ rm $out/bin
+ mkdir $out/bin
+ for i in ${puredata}/bin/*; do
+ ln -s $i $out/bin
+ done
+ fi
+ wrapProgram $out/bin/pd \
+ --add-flags "${toString puredataFlags}"
+ '';
+ };
+in stdenv.lib.overrideDerivation drv (x : { buildInputs = x.buildInputs ++ [ makeWrapper ]; })
diff --git a/pkgs/applications/audio/qjackctl/default.nix b/pkgs/applications/audio/qjackctl/default.nix
index ba875255d4a..9b87dd53bf6 100644
--- a/pkgs/applications/audio/qjackctl/default.nix
+++ b/pkgs/applications/audio/qjackctl/default.nix
@@ -1,14 +1,14 @@
{ stdenv, fetchurl, qt4, alsaLib, jack2, dbus }:
stdenv.mkDerivation rec {
- version = "0.3.11";
+ version = "0.3.12";
name = "qjackctl-${version}";
# some dependencies such as killall have to be installed additionally
src = fetchurl {
url = "mirror://sourceforge/qjackctl/${name}.tar.gz";
- sha256 = "1wjzrgx3n2asyxk6cnfcm34msaw84qvsqy08bd4qnghrgpl96hwl";
+ sha256 = "14yvnc4k3hwsjflg8b2d04bc63pdl0gyqjc7vl6rdn29nbr23zwc";
};
buildInputs = [ qt4 alsaLib jack2 dbus ];
diff --git a/pkgs/applications/audio/qmmp/default.nix b/pkgs/applications/audio/qmmp/default.nix
index a18ef97dd60..0622194d2c2 100644
--- a/pkgs/applications/audio/qmmp/default.nix
+++ b/pkgs/applications/audio/qmmp/default.nix
@@ -28,11 +28,11 @@
# handle that.
stdenv.mkDerivation rec {
- name = "qmmp-0.7.6";
+ name = "qmmp-0.8.2";
src = fetchurl {
url = "http://qmmp.ylsoftware.com/files/${name}.tar.bz2";
- sha256 = "1hq08ii06lyfg516jrvxdfcjj509gvglvdlsr96aqi1fh8v4k5p9";
+ sha256 = "1vwjy3bv1gj6k5kqkhw2q7aspashw6x4lxccl28iydjfzk7d7cd4";
};
buildInputs =
diff --git a/pkgs/applications/audio/qtractor/default.nix b/pkgs/applications/audio/qtractor/default.nix
index 4177dbeeb0c..0ae0c1ef3c8 100644
--- a/pkgs/applications/audio/qtractor/default.nix
+++ b/pkgs/applications/audio/qtractor/default.nix
@@ -3,12 +3,12 @@
, libtool, libvorbis, pkgconfig, qt4, rubberband, stdenv }:
stdenv.mkDerivation rec {
- version = "0.6.2";
+ version = "0.6.5";
name = "qtractor-${version}";
src = fetchurl {
url = "mirror://sourceforge/qtractor/${name}.tar.gz";
- sha256 = "08cr4lgm8bkkmsvfljszcqij3i52n989s7ncrbrn17n61rmgf8yw";
+ sha256 = "0znhm0p9azknmhga6m0qp01qaiahlnfzxya1jf9r05jn9hx5lzf0";
};
buildInputs =
diff --git a/pkgs/applications/audio/samplv1/default.nix b/pkgs/applications/audio/samplv1/default.nix
index 0cbdfa6973d..28473ca365b 100644
--- a/pkgs/applications/audio/samplv1/default.nix
+++ b/pkgs/applications/audio/samplv1/default.nix
@@ -2,11 +2,11 @@
stdenv.mkDerivation rec {
name = "samplv1-${version}";
- version = "0.5.0";
+ version = "0.6.0";
src = fetchurl {
url = "mirror://sourceforge/samplv1/${name}.tar.gz";
- sha256 = "02mm5y1yzklvs5bpxl86y3dqcg7migfybmin8llk91pws6rl9b41";
+ sha256 = "0fbkdb2dqw7v6n8j1h6pjz2019ylli9rmz8awywv2ycm8blr5pf0";
};
buildInputs = [ jack2 libsndfile lv2 qt4 ];
diff --git a/pkgs/applications/audio/schismtracker/default.nix b/pkgs/applications/audio/schismtracker/default.nix
new file mode 100644
index 00000000000..1a448c74b47
--- /dev/null
+++ b/pkgs/applications/audio/schismtracker/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, alsaLib, python, SDL }:
+
+stdenv.mkDerivation rec {
+ version = "20120105";
+ name = "schismtracker-${version}";
+
+ src = fetchurl {
+ url = "http://schismtracker.org/dl/${name}.tar.bz2";
+ sha256 = "1ny7wv2wxm1av299wvpskall6438wjjpadphmqc7c0h6d0zg5kii";
+ };
+
+ configureFlags = "--enable-dependency-tracking";
+
+ buildInputs = [ alsaLib python SDL ];
+
+ meta = {
+ description = "Music tracker application, free reimplementation of Impulse Tracker";
+ homepage = "http://schismtracker.org/";
+ license = stdenv.lib.licenses.gpl2;
+ platforms = [ "x86_64-linux" "i686-linux" ];
+ maintainers = [ stdenv.lib.maintainers.ftrvxmtrx ];
+ };
+}
diff --git a/pkgs/applications/audio/snd/default.nix b/pkgs/applications/audio/snd/default.nix
index 52cd2ad35ce..6048ff88c35 100644
--- a/pkgs/applications/audio/snd/default.nix
+++ b/pkgs/applications/audio/snd/default.nix
@@ -4,17 +4,11 @@
}:
stdenv.mkDerivation rec {
- name = "snd-14.3";
-
- meta = {
- description = "Sound editor";
- homepage = http://ccrma.stanford.edu/software/snd;
- platforms = stdenv.lib.platforms.linux;
- };
+ name = "snd-15.4";
src = fetchurl {
url = "mirror://sourceforge/snd/${name}.tar.gz";
- sha256 = "04shk34pza507kvm40dc6sdz5jz533z4q2h7m9hgqvw1r3f57ms6";
+ sha256 = "1dari02ind445h5hpb6dhi0kix1vmlk64lyxwv1zrqagw3ajmpwh";
};
nativeBuildInputs = [ pkgconfig ];
@@ -23,4 +17,14 @@ stdenv.mkDerivation rec {
gtk2 alsaLib
fftw gsl
];
+
+ meta = {
+ description = "Sound editor";
+ homepage = http://ccrma.stanford.edu/software/snd;
+ platforms = stdenv.lib.platforms.linux;
+ license = stdenv.lib.licenses.free;
+ maintainers = with stdenv.lib.maintainers; [ fuuzetsu ];
+ };
+
+
}
diff --git a/pkgs/applications/audio/sonic-visualiser/default.nix b/pkgs/applications/audio/sonic-visualiser/default.nix
index 42c39062042..7bda4fb2767 100644
--- a/pkgs/applications/audio/sonic-visualiser/default.nix
+++ b/pkgs/applications/audio/sonic-visualiser/default.nix
@@ -8,12 +8,11 @@
stdenv.mkDerivation rec {
name = "sonic-visualiser-${version}";
- version = "2.3";
+ version = "2.4.1";
src = fetchurl {
-
- url = "http://code.soundsoftware.ac.uk/attachments/download/918/${name}.tar.gz";
- sha256 = "1f06w2rin4r2mbi00bg3nmqdi2xdy9vq4jcmfanxzj3ld66ik40c";
+ url = "http://code.soundsoftware.ac.uk/attachments/download/1185/${name}.tar.gz";
+ sha256 = "06nlha70kgrby16nyhngrv5q846xagnxdinv608v7ga7vpywwmyb";
};
buildInputs =
diff --git a/pkgs/applications/audio/sooperlooper/default.nix b/pkgs/applications/audio/sooperlooper/default.nix
new file mode 100644
index 00000000000..b40e2187175
--- /dev/null
+++ b/pkgs/applications/audio/sooperlooper/default.nix
@@ -0,0 +1,34 @@
+{ stdenv, fetchurl, liblo, libxml2, jack2, libsndfile, wxGTK, libsigcxx
+,libsamplerate, rubberband, pkgconfig, ncurses
+}:
+
+stdenv.mkDerivation rec {
+ name = "sooperlooper-${version}";
+ version = "1.7.3";
+ src = fetchurl {
+ url = "http://essej.net/sooperlooper/${name}.tar.gz";
+ sha256 = "0n2gdxw1fx8nxxnpzf4sj0kp6k6zi1yq59cbz6qqzcnsnpnvszbs";
+ };
+
+ buildInputs = [
+ liblo libxml2 jack2 libsndfile wxGTK libsigcxx
+ libsamplerate rubberband pkgconfig ncurses
+ ];
+
+ meta = {
+ description = "A live looping sampler capable of immediate loop recording, overdubbing, multiplying, reversing and more";
+ longDescription = ''
+ It allows for multiple simultaneous multi-channel loops limited only by your computer's available memory.
+ The application is a standalone JACK client with an engine controllable via OSC and MIDI.
+ It also includes a GUI which communicates with the engine via OSC (even over a network) for user-friendly control on a desktop.
+ However, this kind of live performance looping tool is most effectively used via hardware (midi footpedals, etc)
+ and the engine can be run standalone on a computer without a monitor.
+ '';
+
+ version = "${version}";
+ homepage = "http://essej.net/sooperlooper/index.html";
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.magnetophon ];
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/sound-juicer/default.nix b/pkgs/applications/audio/sound-juicer/default.nix
new file mode 100644
index 00000000000..f7f5998846b
--- /dev/null
+++ b/pkgs/applications/audio/sound-juicer/default.nix
@@ -0,0 +1,50 @@
+{ stdenv, fetchurl, pkgconfig, gtk3, intltool, itstool, libxml2, brasero
+, libcanberra_gtk3, gnome3, gst_all_1, libmusicbrainz5, libdiscid, isocodes
+, makeWrapper }:
+
+let
+ major = "3.15";
+ minor = "92";
+ GST_PLUGIN_PATH = stdenv.lib.makeSearchPath "lib/gstreamer-1.0" [
+ gst_all_1.gst-plugins-base
+ gst_all_1.gst-plugins-good
+ gst_all_1.gst-plugins-bad
+ gst_all_1.gst-libav ];
+
+in stdenv.mkDerivation rec {
+ version = "${major}.${minor}";
+ name = "sound-juicer-${version}";
+
+ src = fetchurl {
+ url = "http://download.gnome.org/sources/sound-juicer/${major}/${name}.tar.xz";
+ sha256 = "b1420f267a4c553f6ca242d3b6082b60682c3d7b431ac3c979bd1ccfbf2687dd";
+ };
+
+ buildInputs = [ pkgconfig gtk3 intltool itstool libxml2 brasero libcanberra_gtk3
+ gnome3.gsettings_desktop_schemas libmusicbrainz5 libdiscid isocodes
+ makeWrapper gnome3.dconf
+ gst_all_1.gstreamer gst_all_1.gst-plugins-base
+ gst_all_1.gst-plugins-good gst_all_1.gst-plugins-bad ];
+
+ preFixup = ''
+ for f in $out/bin/* $out/libexec/*; do
+ wrapProgram "$f" \
+ --prefix XDG_DATA_DIRS : "${gnome3.gnome_themes_standard}/share:$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH" \
+ --prefix GST_PLUGIN_SYSTEM_PATH_1_0 : "$GST_PLUGIN_SYSTEM_PATH_1_0" \
+ --prefix GIO_EXTRA_MODULES : "${gnome3.dconf}/lib/gio/modules" \
+ --prefix GST_PLUGIN_PATH : "${GST_PLUGIN_PATH}"
+ done
+ '';
+
+ postInstall = ''
+ rm $out/share/icons/hicolor/icon-theme.cache
+ '';
+
+ meta = with stdenv.lib; {
+ description = "A Gnome CD Ripper";
+ homepage = https://wiki.gnome.org/Apps/SoundJuicer;
+ maintainers = [ maintainers.bdimcheff ];
+ license = licenses.gpl2;
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/audio/spek/default.nix b/pkgs/applications/audio/spek/default.nix
new file mode 100644
index 00000000000..32aac686043
--- /dev/null
+++ b/pkgs/applications/audio/spek/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchzip, autoconf, automake, intltool, pkgconfig, ffmpeg, wxGTK }:
+
+stdenv.mkDerivation rec {
+ name = "spek-${version}";
+ version = "0.8.3";
+
+ src = fetchzip {
+ name = "${name}-src";
+ url = "https://github.com/alexkay/spek/archive/v${version}.tar.gz";
+ sha256 = "0y4hlhswpqkqpsglrhg5xbfy1a6f9fvasgdf336vhwcjqsc3k2xv";
+ };
+
+ buildInputs = [ autoconf automake intltool pkgconfig ffmpeg wxGTK ];
+
+ preConfigure = ''
+ ./autogen.sh
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Analyse your audio files by showing their spectrogram";
+ homepage = http://spek.cc/;
+ license = licenses.gpl3;
+ platforms = platforms.all;
+ maintainers = [ maintainers.bjornfor ];
+ };
+}
diff --git a/pkgs/applications/audio/spotify/default.nix b/pkgs/applications/audio/spotify/default.nix
index 47919a7d7f8..d66029199ce 100644
--- a/pkgs/applications/audio/spotify/default.nix
+++ b/pkgs/applications/audio/spotify/default.nix
@@ -1,6 +1,6 @@
{ fetchurl, stdenv, dpkg, xlibs, qt4, alsaLib, makeWrapper, openssl, freetype
, glib, pango, cairo, atk, gdk_pixbuf, gtk, cups, nspr, nss, libpng, GConf
-, libgcrypt, chromium, sqlite, gst_plugins_base, gstreamer, udev, fontconfig
+, libgcrypt, chromium, udev, fontconfig
, dbus, expat }:
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
@@ -8,21 +8,7 @@ assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
let
version = if stdenv.system == "i686-linux"
then "0.9.4.183.g644e24e.428"
- else "0.9.11.27.g2b1a638.81";
-
- qt4webkit =
- if stdenv.system == "i686-linux" then
- fetchurl {
- name = "libqtwebkit4_2.3.2_i386.deb";
- url = http://ie.archive.ubuntu.com/ubuntu/pool/main/q/qtwebkit-source/libqtwebkit4_2.3.2-0ubuntu7_i386.deb;
- sha256 = "0q4abhczx91ma57fjss0gn8j6nkfbfsbsh6kxhykzj88dih2s8rn";
- }
- else
- fetchurl {
- name = "libqtwebkit4_2.3.2_amd64.deb";
- url = http://ie.archive.ubuntu.com/ubuntu/pool/main/q/qtwebkit-source/libqtwebkit4_2.3.2-0ubuntu7_amd64.deb;
- sha256 = "0sac88avfivwkfhmd6fik7ili8fdznqas6741dbspf9mfnawbwch";
- };
+ else "0.9.17.1.g9b85d43.7";
deps = [
alsaLib
@@ -36,16 +22,13 @@ let
GConf
gdk_pixbuf
glib
- gst_plugins_base
- gstreamer
gtk
libgcrypt
libpng
nss
pango
qt4
- sqlite
- stdenv.gcc.gcc
+ stdenv.cc.cc
xlibs.libX11
xlibs.libXcomposite
xlibs.libXdamage
@@ -56,7 +39,6 @@ let
xlibs.libXrender
xlibs.libXrender
xlibs.libXScrnSaver
- #xlibs.libXss
];
in
@@ -73,7 +55,7 @@ stdenv.mkDerivation {
else if stdenv.system == "x86_64-linux" then
fetchurl {
url = "http://repository.spotify.com/pool/non-free/s/spotify/spotify-client_${version}-1_amd64.deb";
- sha256 = "0yfljiw01kssj3qaz8m0ppgrpjs6xrhzlr2wccp64bsnmin7g4sg";
+ sha256 = "0x87q7gd2997sgppsm4lmdiz1cm11x5vnd5c34nqb5d4ry5qfyki";
}
else throw "Spotify not supported on this platform.";
@@ -83,54 +65,50 @@ stdenv.mkDerivation {
installPhase =
''
- mkdir -p $out
+ libdir=$out/lib/spotify
+ mkdir -p $libdir
dpkg-deb -x $src $out
mv $out/opt/spotify/* $out/
rm -rf $out/usr $out/opt
# Work around Spotify referring to a specific minor version of
# OpenSSL.
- mkdir $out/lib
- ln -s ${nss}/lib/libnss3.so $out/lib/libnss3.so.1d
- ln -s ${nss}/lib/libnssutil3.so $out/lib/libnssutil3.so.1d
- ln -s ${nss}/lib/libsmime3.so $out/lib/libsmime3.so.1d
+ ln -s ${nss}/lib/libnss3.so $libdir/libnss3.so.1d
+ ln -s ${nss}/lib/libnssutil3.so $libdir/libnssutil3.so.1d
+ ln -s ${nss}/lib/libsmime3.so $libdir/libsmime3.so.1d
${if stdenv.system == "x86_64-linux" then ''
- ln -s ${openssl}/lib/libssl.so $out/lib/libssl.so.1.0.0
- ln -s ${openssl}/lib/libcrypto.so $out/lib/libcrypto.so.1.0.0
- ln -s ${nspr}/lib/libnspr4.so $out/lib/libnspr4.so
- ln -s ${nspr}/lib/libplc4.so $out/lib/libplc4.so
+ ln -s ${openssl}/lib/libssl.so $libdir/libssl.so.1.0.0
+ ln -s ${openssl}/lib/libcrypto.so $libdir/libcrypto.so.1.0.0
+ ln -s ${nspr}/lib/libnspr4.so $libdir/libnspr4.so
+ ln -s ${nspr}/lib/libplc4.so $libdir/libplc4.so
'' else ''
- ln -s ${openssl}/lib/libssl.so $out/lib/libssl.so.0.9.8
- ln -s ${openssl}/lib/libcrypto.so $out/lib/libcrypto.so.0.9.8
- ln -s ${nspr}/lib/libnspr4.so $out/lib/libnspr4.so.0d
- ln -s ${nspr}/lib/libplc4.so $out/lib/libplc4.so.0d
+ ln -s ${openssl}/lib/libssl.so $libdir/libssl.so.0.9.8
+ ln -s ${openssl}/lib/libcrypto.so $libdir/libcrypto.so.0.9.8
+ ln -s ${nspr}/lib/libnspr4.so $libdir/libnspr4.so.0d
+ ln -s ${nspr}/lib/libplc4.so $libdir/libplc4.so.0d
''}
- # Work around Spotify trying to open libudev.so.0 (which we don't have)
- ln -s ${udev}/lib/libudev.so.1 $out/lib/libudev.so.0
+ # Work around Spotify trying to open libudev.so.1 (which we don't have)
+ ln -s ${udev}/lib/libudev.so.1 $libdir/libudev.so.1
mkdir -p $out/bin
- rpath="$out/spotify-client/Data:$out/lib:$out/spotify-client:${stdenv.gcc.gcc}/lib64"
+ rpath="$out/spotify-client/Data:$libdir:$out/spotify-client:${stdenv.cc.cc}/lib64"
ln -s $out/spotify-client/spotify $out/bin/spotify
patchelf \
- --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
+ --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
--set-rpath $rpath $out/spotify-client/spotify
patchelf \
- --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
+ --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
--set-rpath $rpath $out/spotify-client/Data/SpotifyHelper
- dpkg-deb -x ${qt4webkit} ./
- mkdir -p $out/lib/
- cp -v usr/lib/*/* $out/lib/
-
preload=$out/libexec/spotify/libpreload.so
- librarypath="${stdenv.lib.makeLibraryPath deps}:$out/lib"
+ librarypath="${stdenv.lib.makeLibraryPath deps}:$libdir"
mkdir -p $out/libexec/spotify
gcc -shared ${./preload.c} -o $preload -ldl -DOUT=\"$out\" -fPIC
@@ -150,6 +128,6 @@ stdenv.mkDerivation {
homepage = https://www.spotify.com/;
description = "Play music from the Spotify music service";
license = stdenv.lib.licenses.unfree;
- maintainers = [ stdenv.lib.maintainers.eelco ];
+ maintainers = with stdenv.lib.maintainers; [ eelco ftrvxmtrx ];
};
}
diff --git a/pkgs/applications/audio/swh-lv2/default.nix b/pkgs/applications/audio/swh-lv2/default.nix
index 9b18ab31abf..2955a9371ff 100644
--- a/pkgs/applications/audio/swh-lv2/default.nix
+++ b/pkgs/applications/audio/swh-lv2/default.nix
@@ -1,15 +1,12 @@
{ stdenv, fetchgit, fftwSinglePrec, libxslt, lv2, pkgconfig }:
-let
- rev = "ec6b85e19e24ed";
-in
stdenv.mkDerivation rec {
- name = "swh-lv2-${rev}";
+ name = "swh-lv2-git-2013-05-17";
src = fetchgit {
- url = "git://github.com/swh/lv2.git";
- inherit rev;
- sha256 = "d0d918ee642cd9649215737fcc008ce2bf55f4ea893a1897138b33775ea60d17";
+ url = "https://github.com/swh/lv2.git";
+ rev = "978d5d8f549fd22048157a6d044af0faeaacbd7f";
+ sha256 = "3a9c042785b856623339aedafa5bc019b41beb8034d8594c7bbd6c9c26368065";
};
patchPhase = ''
diff --git a/pkgs/applications/audio/synthv1/default.nix b/pkgs/applications/audio/synthv1/default.nix
index c6c464b9ad7..83ce2fd66fa 100644
--- a/pkgs/applications/audio/synthv1/default.nix
+++ b/pkgs/applications/audio/synthv1/default.nix
@@ -2,11 +2,11 @@
stdenv.mkDerivation rec {
name = "synthv1-${version}";
- version = "0.5.0";
+ version = "0.6.0";
src = fetchurl {
url = "mirror://sourceforge/synthv1/${name}.tar.gz";
- sha256 = "011kjccrdwb62rpck5gb8h4kvvm8rk6n77lj78ykxz4pxip5hf14";
+ sha256 = "07570mi7rjwkkvfzdw1jcbhpkpxpjp69xj7wfzng92rk2gz7yi8m";
};
buildInputs = [ qt4 jack2 lv2 ];
diff --git a/pkgs/applications/audio/tomahawk/default.nix b/pkgs/applications/audio/tomahawk/default.nix
new file mode 100644
index 00000000000..60e66b9f591
--- /dev/null
+++ b/pkgs/applications/audio/tomahawk/default.nix
@@ -0,0 +1,57 @@
+{ stdenv, fetchurl, cmake, pkgconfig, attica, boost, gnutls, libechonest
+, liblastfm, lucenepp, phonon, phonon_backend_vlc, qca2, qjson, qt4
+, qtkeychain, quazip, sparsehash, taglib, websocketpp, makeWrapper
+
+, enableXMPP ? true, libjreen ? null
+, enableKDE ? false, kdelibs ? null
+, enableTelepathy ? false, telepathy_qt ? null
+}:
+
+assert enableXMPP -> libjreen != null;
+assert enableKDE -> kdelibs != null;
+assert enableTelepathy -> telepathy_qt != null;
+
+let
+ quazipQt4 = quazip.override { qt = qt4; };
+in stdenv.mkDerivation rec {
+ name = "tomahawk-${version}";
+ version = "0.8.2";
+
+ src = fetchurl {
+ url = "http://download.tomahawk-player.org/${name}.tar.bz2";
+ sha256 = "1bmkkpqhflpm42sn6zf7hxv3936h3p0kdiqzmj88jm7qfgw2wbaj";
+ };
+
+ cmakeFlags = [
+ "-DLUCENEPP_INCLUDE_DIR=${lucenepp}/include"
+ "-DLUCENEPP_LIBRARY_DIR=${lucenepp}/lib"
+ ];
+
+ buildInputs = [
+ cmake pkgconfig attica boost gnutls libechonest liblastfm lucenepp phonon
+ qca2 qjson qt4 qtkeychain quazipQt4 sparsehash taglib websocketpp
+ makeWrapper
+ ] ++ stdenv.lib.optional enableXMPP libjreen
+ ++ stdenv.lib.optional enableKDE kdelibs
+ ++ stdenv.lib.optional enableTelepathy telepathy_qt;
+
+ postInstall = let
+ pluginPath = stdenv.lib.concatStringsSep ":" [
+ "${phonon_backend_vlc}/lib/kde4/plugins"
+ ];
+ in ''
+ for i in "$out"/bin/*; do
+ wrapProgram "$i" --prefix QT_PLUGIN_PATH : "${pluginPath}"
+ done
+ '';
+
+ enableParallelBuilding = true;
+
+ meta = with stdenv.lib; {
+ description = "A multi-source music player";
+ homepage = "http://tomahawk-player.org/";
+ license = licenses.gpl3Plus;
+ platforms = platforms.all;
+ maintainers = [ maintainers.aszlig ];
+ };
+}
diff --git a/pkgs/applications/audio/transcode/default.nix b/pkgs/applications/audio/transcode/default.nix
index c414992a12d..f47c8fa2eec 100644
--- a/pkgs/applications/audio/transcode/default.nix
+++ b/pkgs/applications/audio/transcode/default.nix
@@ -17,7 +17,7 @@ stdenv.mkDerivation rec {
enableParallelBuilding = true;
meta = with stdenv.lib; {
- description = "Suite of command line utilities for transcoding video and audio codecs, and for converting beween different container formats";
+ description = "Suite of command line utilities for transcoding video and audio codecs, and for converting between different container formats";
homepage = http://www.transcoding.org/;
license = licenses.lgpl2Plus;
platforms = platforms.linux;
diff --git a/pkgs/applications/audio/vimpc/default.nix b/pkgs/applications/audio/vimpc/default.nix
old mode 100755
new mode 100644
index 3e365cae8e9..71a07f18e08
--- a/pkgs/applications/audio/vimpc/default.nix
+++ b/pkgs/applications/audio/vimpc/default.nix
@@ -26,9 +26,9 @@ stdenv.mkDerivation rec {
'';
meta = {
- description = "A vi/vim inspired client for the Music Player Daemon (mpd).";
+ description = "A vi/vim inspired client for the Music Player Daemon (mpd)";
homepage = https://github.com/boysetsfrog/vimpc;
- license = "GPL3";
+ license = stdenv.lib.licenses.gpl3;
platforms = stdenv.lib.platforms.linux;
};
}
diff --git a/pkgs/applications/audio/vimus/default.nix b/pkgs/applications/audio/vimus/default.nix
new file mode 100644
index 00000000000..7118f1876dc
--- /dev/null
+++ b/pkgs/applications/audio/vimus/default.nix
@@ -0,0 +1,30 @@
+# This file was auto-generated by cabal2nix. Please do NOT edit manually!
+
+{ cabal, c2hs, dataDefault, deepseq, filepath, hspec
+, hspecExpectations, libmpd, mtl, ncurses, QuickCheck, time
+, transformers, utf8String, wcwidth
+}:
+
+cabal.mkDerivation (self: {
+ pname = "vimus";
+ version = "0.2.0";
+ sha256 = "0s7hfyil9rnr9rmjb08g1l1sxybx3qdkw2f59p433fkdjp2m140h";
+ isLibrary = true;
+ isExecutable = true;
+ buildDepends = [
+ dataDefault deepseq filepath libmpd mtl time utf8String wcwidth
+ ];
+ testDepends = [
+ dataDefault hspec hspecExpectations mtl QuickCheck transformers
+ wcwidth
+ ];
+ buildTools = [ c2hs ];
+ extraLibraries = [ ncurses ];
+ meta = {
+ description = "An MPD client with vim-like key bindings";
+ license = self.stdenv.lib.licenses.mit;
+ platforms = self.ghc.meta.platforms;
+ maintainers = with self.stdenv.lib.maintainers; [ jzellner ];
+ broken = self.stdenv.isLinux && self.stdenv.isi686;
+ };
+})
diff --git a/pkgs/applications/audio/yoshimi/default.nix b/pkgs/applications/audio/yoshimi/default.nix
index 67edc7f521d..5277bf6f68c 100644
--- a/pkgs/applications/audio/yoshimi/default.nix
+++ b/pkgs/applications/audio/yoshimi/default.nix
@@ -1,21 +1,21 @@
{ stdenv, fetchurl, alsaLib, boost, cairo, cmake, fftwSinglePrec, fltk
-, jack2, libsndfile, mesa, minixml, pkgconfig, zlib
+, jack2, libsndfile, lv2, mesa, minixml, pkgconfig, zlib, xorg
}:
assert stdenv ? glibc;
stdenv.mkDerivation rec {
name = "yoshimi-${version}";
- version = "1.2.3";
+ version = "1.3.3";
src = fetchurl {
url = "mirror://sourceforge/yoshimi/${name}.tar.bz2";
- sha256 = "00bp699k8gnilin2rvgj35334s9jrizp82qwlmzzvvfliwcgqlqw";
+ sha256 = "0f37xjkay3800fbx0iwjca005b1hrjbhszrzn0xg662vf8mj44nv";
};
buildInputs = [
- alsaLib boost cairo fftwSinglePrec fltk jack2 libsndfile mesa
- minixml zlib
+ alsaLib boost cairo fftwSinglePrec fltk jack2 libsndfile lv2 mesa
+ minixml zlib xorg.libpthreadstubs
];
nativeBuildInputs = [ cmake pkgconfig ];
diff --git a/pkgs/applications/audio/zynaddsubfx/default.nix b/pkgs/applications/audio/zynaddsubfx/default.nix
index a5aa7d5c8d9..3a89b406742 100644
--- a/pkgs/applications/audio/zynaddsubfx/default.nix
+++ b/pkgs/applications/audio/zynaddsubfx/default.nix
@@ -1,17 +1,17 @@
-{ stdenv, fetchurl, alsaLib, cmake, jack2, fftw, fltk13, minixml
-, pkgconfig, zlib
+{ stdenv, fetchurl, alsaLib, cmake, jack2, fftw, fltk13, libjpeg
+, minixml, pkgconfig, zlib
}:
stdenv.mkDerivation rec {
name = "zynaddsubfx-${version}";
- version = "2.4.3";
+ version = "2.4.4";
src = fetchurl {
- url = "mirror://sourceforge/zynaddsubfx/ZynAddSubFX-${version}.tar.bz2";
- sha256 = "0kgmwyh4rhyqdfrdzhbzjjk2hzggkp9c4aac6sy3xv6cc1b5jjxq";
+ url = "mirror://sourceforge/zynaddsubfx/zynaddsubfx-${version}.tar.xz";
+ sha256 = "15byz08p5maf3v8l1zz11xan6s0qcfasjf1b81xc8rffh13x5f53";
};
- buildInputs = [ alsaLib jack2 fftw fltk13 minixml zlib ];
+ buildInputs = [ alsaLib jack2 fftw fltk13 libjpeg minixml zlib ];
nativeBuildInputs = [ cmake pkgconfig ];
meta = with stdenv.lib; {
diff --git a/pkgs/applications/backup/crashplan/CrashPlanDesktop.patch b/pkgs/applications/backup/crashplan/CrashPlanDesktop.patch
new file mode 100644
index 00000000000..00516484890
--- /dev/null
+++ b/pkgs/applications/backup/crashplan/CrashPlanDesktop.patch
@@ -0,0 +1,8 @@
+--- ./scripts/CrashPlanDesktop 2014-12-18 09:51:14.050804325 +0100
++++ ./scripts/CrashPlanDesktop-1 2014-12-18 09:51:32.271009382 +0100
+@@ -9,4 +9,4 @@
+
+ cd ${TARGETDIR}
+
+-${JAVACOMMON} ${GUI_JAVA_OPTS} -classpath "./lib/com.backup42.desktop.jar:./lang:./skin" com.backup42.desktop.CPDesktop > ${TARGETDIR}/log/ui_output.log 2> ${TARGETDIR}/log/ui_error.log &
++${JAVACOMMON} ${GUI_JAVA_OPTS} -classpath "./lib/com.backup42.desktop.jar:./lang:./skin" com.backup42.desktop.CPDesktop &
diff --git a/pkgs/applications/backup/crashplan/CrashPlanEngine.patch b/pkgs/applications/backup/crashplan/CrashPlanEngine.patch
new file mode 100644
index 00000000000..de2afe2da68
--- /dev/null
+++ b/pkgs/applications/backup/crashplan/CrashPlanEngine.patch
@@ -0,0 +1,37 @@
+--- ./scripts/CrashPlanEngine 2014-02-19 23:17:19.000000000 +0000
++++ ./scripts/CrashPlanEngine.1 2014-07-24 17:36:37.330333581 +0100
+@@ -11,7 +11,7 @@
+
+ cd $TARGETDIR
+
+- nice -n 19 $JAVACOMMON $SRV_JAVA_OPTS -classpath $FULL_CP com.backup42.service.CPService > $TARGETDIR/log/engine_output.log 2> $TARGETDIR/log/engine_error.log &
++ nice -n 19 $JAVACOMMON $SRV_JAVA_OPTS -classpath $FULL_CP com.backup42.service.CPService > $VARDIR/log/engine_output.log 2> $VARDIR/log/engine_error.log &
+
+ if [[ $! -gt 0 ]]; then
+ echo $! > $PIDFILE
+@@ -26,7 +26,7 @@
+
+ echo "Using Ubuntu 9.04 startup"
+
+- start-stop-daemon -v --pidfile $PIDFILE --make-pidfile --background --chdir $TARGETDIR --start --nicelevel 19 --exec $JAVACOMMON -- $SRV_JAVA_OPTS -classpath $FULL_CP com.backup42.service.CPService > $TARGETDIR/log/engine_output.log 2> $TARGETDIR/log/engine_error.log
++ start-stop-daemon -v --pidfile $PIDFILE --make-pidfile --background --chdir $TARGETDIR --start --nicelevel 19 --exec $JAVACOMMON -- $SRV_JAVA_OPTS -classpath $FULL_CP com.backup42.service.CPService > $VARDIR/log/engine_output.log 2> $VARDIR/log/engine_error.log
+
+ # This test isn't as useful as one might like; start-stop-daemon can't accurately report the state of child processes when --background is used.
+ # We use this mainly to report the specific error value returned by start-stop-daemon if something goes wrong, but be aware that a return value
+@@ -91,7 +91,6 @@
+ DESC="CrashPlan Engine"
+ NAME=CrashPlanEngine
+ DAEMON=$TARGETDIR/lib/com.backup42.desktop.jar
+-PIDFILE="$TARGETDIR/${NAME}.pid"
+
+ if [[ -f $TARGETDIR/install.vars ]]; then
+ . $TARGETDIR/install.vars
+@@ -100,6 +99,8 @@
+ exit 1
+ fi
+
++PIDFILE="$VARDIR/${NAME}.pid"
++
+ if [[ ! -f $DAEMON ]]; then
+ echo "Could not find JAR file $DAEMON"
+ exit 0
diff --git a/pkgs/applications/backup/crashplan/default.nix b/pkgs/applications/backup/crashplan/default.nix
new file mode 100644
index 00000000000..5a0e8c7cfbd
--- /dev/null
+++ b/pkgs/applications/backup/crashplan/default.nix
@@ -0,0 +1,83 @@
+{ stdenv, fetchurl, makeWrapper, jre, cpio, gawk, gnugrep, gnused, procps, swt, gtk2, glib, libXtst }:
+
+let version = "3.6.4";
+
+in stdenv.mkDerivation rec {
+ name = "crashplan-${version}";
+
+ crashPlanArchive = fetchurl {
+ url = "http://download.crashplan.com/installs/linux/install/CrashPlan/CrashPlan_${version}_Linux.tgz";
+ sha256 = "0xmzpxfm8vghk552jy167wg1nky1pp93dqds1p922hn73g0x5cv3";
+ };
+
+ srcs = [ crashPlanArchive ];
+
+ meta = with stdenv.lib; {
+ description = "An online/offline backup solution";
+ homepage = "http://www.crashplan.org";
+ license = licenses.unfree;
+ maintainers = with maintainers; [ sztupi iElectric ];
+ };
+
+ buildInputs = [ makeWrapper cpio ];
+
+ vardir = "/var/lib/crashplan";
+
+ manifestdir = "${vardir}/manifest";
+
+ patches = [ ./CrashPlanEngine.patch ./CrashPlanDesktop.patch ];
+
+ installPhase = ''
+ mkdir $out
+ zcat -v CrashPlan_${version}.cpi | (cd $out; cpio -i -d -v --no-preserve-owner)
+
+ # sed -i "s|manifest |${manifestdir} |g" $out/conf/default.service.xml
+
+ # Fix for encoding troubles (CrashPlan ticket 178827)
+ # Make sure the daemon is running using the same localization as
+ # the (installing) user
+ echo "" >> run.conf
+ echo "export LC_ALL=en_US.UTF-8" >> run.conf
+
+ install -d -m 755 unpacked $out
+
+ install -D -m 644 EULA.txt $out/EULA.txt
+ install -D -m 644 run.conf $out/bin/run.conf
+ install -D -m 755 scripts/CrashPlanDesktop $out/bin/CrashPlanDesktop
+ install -D -m 755 scripts/CrashPlanEngine $out/bin/CrashPlanEngine
+ install -D -m 644 scripts/CrashPlan.desktop $out/share/applications/CrashPlan.desktop
+
+ rm -r $out/log
+ ln -s $vardir/log $out/log
+ ln -s $vardir/cache $out/cache
+ ln -s $vardir/backupArchives $out/backupArchives
+ ln -s $vardir/conf/service.model $out/conf/service.model
+ ln -s $vardir/conf/my.service.xml $out/conf/my.service.xml
+
+ echo "JAVACOMMON=${jre}/bin/java" > $out/install.vars
+ echo "APP_BASENAME=CrashPlan" >> $out/install.vars
+ echo "TARGETDIR=$out" >> $out/install.vars
+ echo "BINSDIR=$out/bin" >> $out/install.vars
+ echo "MANIFESTDIR=${manifestdir}" >> $out/install.vars
+ echo "VARDIR=${vardir}" >> $out/install.vars
+ echo "INITDIR=" >> $out/install.vars
+ echo "RUNLVLDIR=" >> $out/install.vars
+ echo "INSTALLDATE=" >> $out/install.vars
+ '';
+
+ postFixup = ''
+ for f in $out/bin/CrashPlanDesktop $out/bin/CrashPlanEngine; do
+ echo "substitutions in $f"
+ substituteInPlace $f --replace /bin/ps ${procps}/bin/ps
+ substituteInPlace $f --replace awk ${gawk}/bin/awk
+ substituteInPlace $f --replace sed ${gnused}/bin/sed
+ substituteInPlace $f --replace grep ${gnugrep}/bin/grep
+ done
+
+ substituteInPlace $out/share/applications/CrashPlan.desktop \
+ --replace /usr/local $out \
+ --replace crashplan/skin skin
+
+ wrapProgram $out/bin/CrashPlanDesktop --prefix LD_LIBRARY_PATH ":" "${gtk2}/lib:${glib}/lib:${libXtst}/lib"
+ '';
+}
diff --git a/pkgs/applications/display-managers/lightdm-gtk-greeter/default.nix b/pkgs/applications/display-managers/lightdm-gtk-greeter/default.nix
index 69f1eef9cec..2ae6b2aeb26 100644
--- a/pkgs/applications/display-managers/lightdm-gtk-greeter/default.nix
+++ b/pkgs/applications/display-managers/lightdm-gtk-greeter/default.nix
@@ -6,45 +6,42 @@
#ToDo: bad icons with gtk2;
# avatar icon is missing in standard hicolor theme, I don't know where gtk3 takes it from
-#ToDo: Failed to open sessions directory: Error opening directory '${lightdm}/share/lightdm/remote-sessions': No such file or directory
-
let
- ver_branch = "1.6";
- version = "1.6.1";
+ ver_branch = "2.0";
+ version = "2.0.0";
in
stdenv.mkDerivation rec {
name = "lightdm-gtk-greeter-${version}";
src = fetchurl {
url = "${meta.homepage}/${ver_branch}/${version}/+download/${name}.tar.gz";
- sha256 = "1nb8ljrbrp1zga083g3b633xi3izxxm4jipw1qgial1x16mqc0hz";
+ sha256 = "1134q8qd7gr34jkivqxckdnwbpa8pl7dhjpdi9fci0pcs4hh22jc";
};
- patches = [
- ./lightdm-gtk-greeter.patch
- (fetchurl { # CVE-2014-0979, https://bugs.launchpad.net/lightdm-gtk-greeter/+bug/1266449
- url = "https://launchpadlibrarian.net/161796033/07_fix-NULL-username.patch";
- sha256 = "1sqkhsz1z10k6vlmlrqrfx452lznv30885fmnzc73p2zxdlw9q1a";
- })
+ buildInputs = [ pkgconfig lightdm intltool makeWrapper ]
+ ++ (if useGTK2 then [ gtk2 ] else [ gtk3 ]);
+
+ configureFlags = [
+ "--localstatedir=/var"
+ "--sysconfdir=/etc"
+ ] ++ stdenv.lib.optional useGTK2 "--with-gtk2";
+
+ installFlags = [
+ "localstatedir=\${TMPDIR}"
+ "sysconfdir=\${out}/etc"
];
- patchFlags = "-p1";
-
- buildInputs = [ pkgconfig lightdm intltool ]
- ++ (if useGTK2 then [ gtk2 makeWrapper ] else [ gtk3 ]);
-
- configureFlags = stdenv.lib.optional useGTK2 "--with-gtk2";
postInstall = ''
- substituteInPlace "$out/share/xgreeters/lightdm-gtk-greeter.desktop" \
- --replace "Exec=lightdm-gtk-greeter" "Exec=$out/sbin/lightdm-gtk-greeter"
- '' + stdenv.lib.optionalString useGTK2 ''
- wrapProgram "$out/sbin/lightdm-gtk-greeter" \
- --prefix XDG_DATA_DIRS ":" "${hicolor_icon_theme}/share"
- '';
+ substituteInPlace "$out/share/xgreeters/lightdm-gtk-greeter.desktop" \
+ --replace "Exec=lightdm-gtk-greeter" "Exec=$out/sbin/lightdm-gtk-greeter"
+ wrapProgram "$out/sbin/lightdm-gtk-greeter" \
+ --prefix XDG_DATA_DIRS ":" "${hicolor_icon_theme}/share"
+ '';
- meta = {
+ meta = with stdenv.lib; {
homepage = http://launchpad.net/lightdm-gtk-greeter;
- platforms = stdenv.lib.platforms.linux;
- maintainers = [ stdenv.lib.maintainers.ocharles ];
+ platforms = platforms.linux;
+ license = licenses.gpl3;
+ maintainers = with maintainers; [ ocharles wkennington ];
};
}
diff --git a/pkgs/applications/display-managers/lightdm-gtk-greeter/lightdm-gtk-greeter.patch b/pkgs/applications/display-managers/lightdm-gtk-greeter/lightdm-gtk-greeter.patch
deleted file mode 100644
index ea9e0eaec93..00000000000
--- a/pkgs/applications/display-managers/lightdm-gtk-greeter/lightdm-gtk-greeter.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c
-index cc5f9e1..d615dc1 100644
---- a/src/lightdm-gtk-greeter.c
-+++ b/src/lightdm-gtk-greeter.c
-@@ -1716,7 +1716,7 @@ main (int argc, char **argv)
- gtk_container_add (GTK_CONTAINER (menuitem), image);
- gtk_widget_show (GTK_WIDGET (menuitem));
-
-- items = lightdm_get_sessions ();
-+ items = lightdm_get_sessions (greeter);
- GSList *sessions = NULL;
- for (item = items; item; item = item->next)
- {
diff --git a/pkgs/applications/display-managers/lightdm/default.nix b/pkgs/applications/display-managers/lightdm/default.nix
index d4c6f24d69a..79163945c0c 100644
--- a/pkgs/applications/display-managers/lightdm/default.nix
+++ b/pkgs/applications/display-managers/lightdm/default.nix
@@ -1,32 +1,41 @@
{ stdenv, fetchurl, pam, pkgconfig, libxcb, glib, libXdmcp, itstool, libxml2
-, intltool, x11, libxklavier, libgcrypt, dbus/*for tests*/ }:
+, intltool, x11, libxklavier, libgcrypt
+, qt4 ? null, qt5 ? null
+}:
let
- ver_branch = "1.8";
- version = "1.8.6";
+ ver_branch = "1.14";
+ version = "1.14.0";
in
stdenv.mkDerivation rec {
name = "lightdm-${version}";
src = fetchurl {
url = "${meta.homepage}/${ver_branch}/${version}/+download/${name}.tar.xz";
- sha256 = "17ivc0c4dbnc0fzd581j53cn6hdav34zz2hswjzy8aczbpk605qi";
+ sha256 = "0fkbzqncx34dhylrg5328fih7xywmsqj2p40smnx33nyf047jdgc";
};
- patches = [ ./lightdm.patch ];
- patchFlags = "-p1";
-
buildInputs = [
pkgconfig pam libxcb glib libXdmcp itstool libxml2 intltool libxklavier libgcrypt
- ] ++ stdenv.lib.optional doCheck dbus.daemon;
+ qt4 qt5
+ ];
- configureFlags = [ "--enable-liblightdm-gobject" "--localstatedir=/var" ];
+ configureFlags = [
+ "--enable-liblightdm-gobject"
+ "--localstatedir=/var"
+ "--sysconfdir=/etc"
+ ] ++ stdenv.lib.optional (qt4 != null) "--enable-liblightdm-qt"
+ ++ stdenv.lib.optional (qt5 != null) "--enable-liblightdm-qt5";
- doCheck = false; # some tests fail, don't know why
+ installFlags = [
+ "sysconfdir=\${out}/etc"
+ "localstatedir=\${TMPDIR}"
+ ];
- meta = {
+ meta = with stdenv.lib; {
homepage = http://launchpad.net/lightdm;
- platforms = stdenv.lib.platforms.linux;
- maintainers = [ stdenv.lib.maintainers.ocharles ];
+ platforms = platforms.linux;
+ license = licenses.gpl3;
+ maintainers = with maintainers; [ ocharles wkennington ];
};
}
diff --git a/pkgs/applications/display-managers/lightdm/lightdm.patch b/pkgs/applications/display-managers/lightdm/lightdm.patch
deleted file mode 100644
index d81e0aae56d..00000000000
--- a/pkgs/applications/display-managers/lightdm/lightdm.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-diff --git a/liblightdm-gobject/greeter.c b/liblightdm-gobject/greeter.c
-index 9387118..635cea0 100644
---- a/liblightdm-gobject/greeter.c
-+++ b/liblightdm-gobject/greeter.c
-@@ -567,6 +567,21 @@ lightdm_greeter_get_default_session_hint (LightDMGreeter *greeter)
- }
-
- /**
-+ * lightdm_greeter_get_config_path
-+ * @greeter: A #LightDMGreeter
-+ *
-+ * Get the config path to LightDM.
-+ *
-+ * Return value: The path to the current LightDM configuration file.
-+ **/
-+const gchar *
-+lightdm_greeter_get_config_path (LightDMGreeter *greeter)
-+{
-+ g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL);
-+ return lightdm_greeter_get_hint (greeter, "config-path");
-+}
-+
-+/**
- * lightdm_greeter_get_hide_users_hint:
- * @greeter: A #LightDMGreeter
- *
-diff --git a/liblightdm-gobject/lightdm/greeter.h b/liblightdm-gobject/lightdm/greeter.h
-index 7d8988f..2b54909 100644
---- a/liblightdm-gobject/lightdm/greeter.h
-+++ b/liblightdm-gobject/lightdm/greeter.h
-@@ -93,6 +93,8 @@ gboolean lightdm_greeter_get_select_guest_hint (LightDMGreeter *greeter);
-
- const gchar *lightdm_greeter_get_autologin_user_hint (LightDMGreeter *greeter);
-
-+const gchar *lightdm_greeter_get_config_path (LightDMGreeter *greeter);
-+
- gboolean lightdm_greeter_get_autologin_guest_hint (LightDMGreeter *greeter);
-
- gint lightdm_greeter_get_autologin_timeout_hint (LightDMGreeter *greeter);
-diff --git a/liblightdm-gobject/lightdm/session.h b/liblightdm-gobject/lightdm/session.h
-index 13ddcd9..cdb2fd6 100644
---- a/liblightdm-gobject/lightdm/session.h
-+++ b/liblightdm-gobject/lightdm/session.h
-@@ -12,6 +12,7 @@
- #define LIGHTDM_SESSION_H_
-
- #include
-+#include "greeter.h"
-
- G_BEGIN_DECLS
-
-@@ -42,9 +43,9 @@ typedef struct
-
- GType lightdm_session_get_type (void);
-
--GList *lightdm_get_sessions (void);
-+GList *lightdm_get_sessions (LightDMGreeter *greeter);
-
--GList *lightdm_get_remote_sessions (void);
-+GList *lightdm_get_remote_sessions (LightDMGreeter *greeter);
-
- const gchar *lightdm_session_get_key (LightDMSession *session);
-
-diff --git a/liblightdm-gobject/session.c b/liblightdm-gobject/session.c
-index 949778f..db5e18a 100644
---- a/liblightdm-gobject/session.c
-+++ b/liblightdm-gobject/session.c
-@@ -11,6 +11,7 @@
- #include
- #include
-
-+#include "lightdm/greeter.h"
- #include "lightdm/session.h"
-
- enum {
-@@ -189,7 +190,7 @@ load_sessions (const gchar *sessions_dir)
- }
-
- static void
--update_sessions (void)
-+update_sessions (LightDMGreeter *greeter)
- {
- GKeyFile *config_key_file = NULL;
- gchar *config_path = NULL;
-@@ -205,8 +206,7 @@ update_sessions (void)
- remote_sessions_dir = g_strdup (REMOTE_SESSIONS_DIR);
-
- /* Use session directory from configuration */
-- /* FIXME: This should be sent in the greeter connection */
-- config_path = g_build_filename (CONFIG_DIR, "lightdm.conf", NULL);
-+ config_path = g_strdup (lightdm_greeter_get_config_path (greeter));
- config_key_file = g_key_file_new ();
- result = g_key_file_load_from_file (config_key_file, config_path, G_KEY_FILE_NONE, &error);
- if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
-@@ -250,9 +250,9 @@ update_sessions (void)
- * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
- **/
- GList *
--lightdm_get_sessions (void)
-+lightdm_get_sessions (LightDMGreeter *greeter)
- {
-- update_sessions ();
-+ update_sessions (greeter);
- return local_sessions;
- }
-
-@@ -264,9 +264,9 @@ lightdm_get_sessions (void)
- * Return value: (element-type LightDMSession) (transfer none): A list of #LightDMSession
- **/
- GList *
--lightdm_get_remote_sessions (void)
-+lightdm_get_remote_sessions (LightDMGreeter *greeter)
- {
-- update_sessions ();
-+ update_sessions (greeter);
- return remote_sessions;
- }
-
-diff --git a/src/lightdm.c b/src/lightdm.c
-index 7d35034..910164c 100644
---- a/src/lightdm.c
-+++ b/src/lightdm.c
-@@ -1142,6 +1142,9 @@ main (int argc, char **argv)
- }
- }
- g_clear_error (&error);
-+
-+ config_set_string (config_get_instance (), "SeatDefaults", "config-path", config_path);
-+
- g_free (config_path);
-
- /* Set default values */
-diff --git a/src/seat.c b/src/seat.c
-index e2b9c2c..a950ea2 100644
---- a/src/seat.c
-+++ b/src/seat.c
-@@ -1137,6 +1137,7 @@ create_greeter_session (Seat *seat)
- greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
- greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
- greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
-+ greeter_set_hint (greeter_session, "config-path", seat_get_string_property (seat, "config-path"));
-
- g_object_unref (session_config);
-
diff --git a/pkgs/applications/display-managers/sddm/cmake_paths.patch b/pkgs/applications/display-managers/sddm/cmake_paths.patch
new file mode 100644
index 00000000000..7deb3e2e1bd
--- /dev/null
+++ b/pkgs/applications/display-managers/sddm/cmake_paths.patch
@@ -0,0 +1,55 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 4d6e0a9..df4ad28 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -77,7 +77,9 @@ find_package(Qt5LinguistTools REQUIRED)
+
+ # find qt5 imports dir
+ get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
+-exec_program(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_QML" RETURN_VALUE return_code OUTPUT_VARIABLE QT_IMPORTS_DIR)
++if(NOT QT_IMPORTS_DIR)
++ exec_program(${QMAKE_EXECUTABLE} ARGS "-query QT_INSTALL_QML" RETURN_VALUE return_code OUTPUT_VARIABLE QT_IMPORTS_DIR)
++endif()
+
+ # Set components version
+ set(COMPONENTS_VERSION 2.0)
+diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in
+index 6a28224..798bc5c 100644
+--- a/data/man/sddm.conf.rst.in
++++ b/data/man/sddm.conf.rst.in
+@@ -65,6 +65,10 @@ OPTIONS
+ Path of the X server.
+ Default value is "/usr/bin/X".
+
++`XephyrPath=`
++ Path of the Xephyr.
++ Default value is "/usr/bin/Xephyr".
++
+ `XauthPath=`
+ Path of the Xauth.
+ Default value is "/usr/bin/xauth".
+diff --git a/src/common/Configuration.h b/src/common/Configuration.h
+index 72aa6f4..854cc22 100644
+--- a/src/common/Configuration.h
++++ b/src/common/Configuration.h
+@@ -54,6 +54,7 @@ namespace SDDM {
+ // TODO: Not absolutely sure if everything belongs here. Xsessions, VT and probably some more seem universal
+ Section(XDisplay,
+ Entry(ServerPath, QString, _S("/usr/bin/X"), _S("X server path"));
++ Entry(XephyrPath, QString, _S("/usr/bin/Xephyr"), _S("Xephyr path"));
+ Entry(XauthPath, QString, _S("/usr/bin/xauth"), _S("Xauth path"));
+ Entry(SessionDir, QString, _S("/usr/share/xsessions"), _S("Session description directory"));
+ Entry(SessionCommand, QString, _S(SESSION_COMMAND), _S("Xsession script path\n"
+diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp
+index f10ad82..cb9de3f 100644
+--- a/src/daemon/XorgDisplayServer.cpp
++++ b/src/daemon/XorgDisplayServer.cpp
+@@ -136,7 +136,7 @@ namespace SDDM {
+ if (daemonApp->testing()) {
+ QStringList args;
+ args << m_display << "-ac" << "-br" << "-noreset" << "-screen" << "800x600";
+- process->start("/usr/bin/Xephyr", args);
++ process->start(mainConfig.XDisplay.XephyrPath.get(), args);
+ } else {
+ // set process environment
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
diff --git a/pkgs/applications/display-managers/sddm/default.nix b/pkgs/applications/display-managers/sddm/default.nix
new file mode 100644
index 00000000000..73a188af0cf
--- /dev/null
+++ b/pkgs/applications/display-managers/sddm/default.nix
@@ -0,0 +1,47 @@
+{ stdenv, fetchpatch, makeWrapper, fetchFromGitHub, cmake, pkgconfig, libxcb, libpthreadstubs
+, libXdmcp, libXau, qt5, pam, systemd }:
+
+let
+ version = "0.11.0";
+in
+stdenv.mkDerivation rec {
+ name = "sddm-${version}";
+
+ src = fetchFromGitHub {
+ owner = "sddm";
+ repo = "sddm";
+ rev = "v${version}";
+ sha256 = "1s1gm0xvgwzrpxgni3ngdj8phzg21gkk1jyiv2l2i5ayl0jdm7ig";
+ };
+
+ nativeBuildInputs = [ cmake pkgconfig qt5.tools makeWrapper ];
+
+ buildInputs = [ libxcb libpthreadstubs libXdmcp libXau qt5.base pam systemd ];
+
+ patches = [ (fetchpatch {
+ url = "https://github.com/sddm/sddm/commit/9bc21ee7da5de6b2531d47d1af4d7b0a169990b9.patch";
+ sha256 = "1pda0wf4xljdadja7iyh5c48h0347imadg9ya1dw5slgb7w1d94l";
+ })
+ ./cmake_paths.patch
+ ];
+
+ cmakeFlags = [ "-DCONFIG_FILE=/etc/sddm.conf" ];
+
+ preConfigure = ''
+ export cmakeFlags="$cmakeFlags -DQT_IMPORTS_DIR=$out/lib/qt5/qml -DCMAKE_INSTALL_SYSCONFDIR=$out/etc -DSYSTEMD_SYSTEM_UNIT_DIR=$out/lib/systemd/system"
+ '';
+
+ postInstall = ''
+ wrapProgram $out/bin/sddm-greeter \
+ --set QML2_IMPORT_PATH "${qt5.declarative}/lib/qt5/qml/"
+ '';
+
+ enableParallelBuilding = true;
+
+ meta = with stdenv.lib; {
+ description = "QML based X11 display manager";
+ homepage = http://launchpad.net/lightdm;
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ abbradar ];
+ };
+}
diff --git a/pkgs/applications/display-managers/slim/themes.nix b/pkgs/applications/display-managers/slim/themes.nix
new file mode 100644
index 00000000000..0c69f101885
--- /dev/null
+++ b/pkgs/applications/display-managers/slim/themes.nix
@@ -0,0 +1,183 @@
+{ stdenv, fetchurl, slim }:
+
+# Inspired on aspell buildDict expression
+
+let
+ buildTheme =
+ {fullName, src, version ? "testing"}:
+
+ stdenv. mkDerivation rec {
+ name = "${fullName}-${version}";
+
+ inherit src;
+
+ buildInputs = [ slim ];
+
+ dontBuild = true;
+
+ installPhase = ''
+ install -dm755 $out/share/slim/themes/${name}
+ install -m644 * $out/share/slim/themes/${name}
+ '';
+
+ meta = {
+ description = "Slim theme for ${fullName}";
+ platforms = stdenv.lib.platforms.linux;
+ };
+ };
+
+in {
+
+ archlinuxSimple = buildTheme {
+ fullName = "archlinux-simple";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-archlinux-simple.tar.gz";
+ sha256 = "7d60d6782fa86302646fe67253467c04692d247f89bdbe87178f690f32b270db";
+ };
+ };
+
+ capernoited = buildTheme {
+ fullName = "capernoited";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-capernoited.tar.gz";
+ sha256 = "fb9163c6a2656d60f088dc4f2173aa7556a6794495122acfa7d3be7182f16b41";
+ };
+ };
+
+ debianMoreblue = buildTheme {
+ fullName = "debian-moreblue";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-debian-moreblue.tar.bz2";
+ sha256 = "5b76929827d4a4d604ddca4f42668cca3309b6f7bd659901021c6f49d6d2c481";
+ };
+ };
+
+ fingerprint = buildTheme {
+ fullName = "fingerprint";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-fingerprint.tar.gz";
+ sha256 = "48b703f84ce7b814cda0824f65cafebf695cd71a14166b481bb44616097d3144";
+ };
+ };
+
+ flat = buildTheme {
+ fullName = "flat";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-flat.tar.gz";
+ sha256 = "0092d531540f9da8ef07ad173e527c4ef9c088d04962d142be3c11f0c5c0c5e9";
+ };
+ };
+
+ flower2 = buildTheme {
+ fullName = "flower2";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-flower2.tar.gz";
+ sha256 = "840faf6459ffd6c2c363160c85cb98000717f9a425102976336f5d8f68ed95ee";
+ };
+ };
+
+ gentooSimple = buildTheme {
+ fullName = "gentoo-simple";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-gentoo-simple.tar.bz2";
+ sha256 = "27c8614cc930ca200acf81f1192febc102501744939d5cbe997141e37c96d8c2";
+ };
+ };
+
+ lake = buildTheme {
+ fullName = "lake";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-lake.tar.gz";
+ sha256 = "f7d662e37068a6c64cbf910adf3c192f1b50724baa427a8c9487cb9f7ed95851";
+ };
+ };
+
+ lunar = buildTheme {
+ fullName = "lunar-0.4";
+ version = "";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-lunar-0.4.tar.bz2";
+ sha256 = "1543eb45e4d664377e0dd4f7f954aba005823034ba9692624398b3d58be87d76";
+ };
+ };
+
+ mindlock = buildTheme {
+ fullName = "mindlock";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-mindlock.tar.gz";
+ sha256 = "99a6e6acd55bf55ece18a3f644299517b71c1adc49efd87ce2d7e654fb67033c";
+ };
+ };
+
+ parallelDimensions = buildTheme {
+ fullName = "parallel-dimensions";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-parallel-dimensions.tar.gz";
+ sha256 = "2b17c3e6d3967a6a0744e20e6e05c9d3938f4ef04c62d49ddbd416bc4743046f";
+ };
+ };
+
+ previous = buildTheme {
+ fullName = "previous";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-previous.tar.gz";
+ sha256 = "1f2a69f8fc0dc8ed8eb86a4c1d1087ba7be486973fb81efab52a63c661d726f8";
+ };
+ };
+
+ rainbow = buildTheme {
+ fullName = "rainbow";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-rainbow.tar.gz";
+ sha256 = "d83e3afdb05be50cff7da037bb31208b2c152539d1a009740b13857f5f910072";
+ };
+ };
+
+ rear-window = buildTheme {
+ fullName = "rear-window";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-rear-window.tar.gz";
+ sha256 = "0b123706ccb67e94f626c183530ec5732b209bab155bc661d6a3f5cd5ee39511";
+ };
+ };
+
+ scotlandRoad = buildTheme {
+ fullName = "scotland-road";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-scotland-road.tar.gz";
+ sha256 = "fd60a434496ed39b968ffa1e5457b36cd12f64a4e2ecedffc675f97ca3f3bba1";
+ };
+ };
+
+ subway = buildTheme {
+ fullName = "subway";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-subway.tar.gz";
+ sha256 = "0205568e3e157973b113a83b26d8829ce9962a85ef7eb8a33d3ae2f3f9292253";
+ };
+ };
+
+ wave = buildTheme {
+ fullName = "wave";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-wave.tar.gz";
+ sha256 = "be75676da5bf8670daa48379bb9cc1be0b9a5faa09adbea967dfd7125320b959";
+ };
+ };
+
+ zenwalk = buildTheme {
+ fullName = "zenwalk";
+ src = fetchurl {
+ url = "mirror://sourceforge/slim.berlios/slim-zenwalk.tar.gz";
+ sha256 = "f0f41d17ea505b0aa96a036e978fabaf673a51d3f81a919cb0d43364d4bc7a57";
+ };
+ };
+
+ nixosSlim = buildTheme {
+ fullName = "nixos-slim";
+ src = fetchurl {
+ url = "https://github.com/jagajaga/nixos-slim-theme/archive/1.1.tar.gz";
+ sha256 = "66c3020a6716130a20c3898567339b990fbd7888a3b7bbcb688f6544d1c05c31";
+ };
+ };
+}
diff --git a/pkgs/applications/editors/atom/default.nix b/pkgs/applications/editors/atom/default.nix
index 51844f64179..a3cdbb6afb9 100644
--- a/pkgs/applications/editors/atom/default.nix
+++ b/pkgs/applications/editors/atom/default.nix
@@ -1,61 +1,46 @@
{ stdenv, fetchurl, buildEnv, makeDesktopItem, makeWrapper, zlib, glib, alsaLib
, dbus, gtk, atk, pango, freetype, fontconfig, libgnome_keyring3, gdk_pixbuf
-, cairo, cups, expat, libgpgerror, nspr, gconf, nss, xlibs
+, cairo, cups, expat, libgpgerror, nspr, gconf, nss, xlibs, libcap
}:
let
atomEnv = buildEnv {
name = "env-atom";
paths = [
- stdenv.gcc.gcc zlib glib dbus gtk atk pango freetype libgnome_keyring3
+ stdenv.cc.cc zlib glib dbus gtk atk pango freetype libgnome_keyring3
fontconfig gdk_pixbuf cairo cups expat libgpgerror alsaLib nspr gconf nss
xlibs.libXrender xlibs.libX11 xlibs.libXext xlibs.libXdamage xlibs.libXtst
- xlibs.libXcomposite xlibs.libXi xlibs.libXfixes
+ xlibs.libXcomposite xlibs.libXi xlibs.libXfixes xlibs.libXrandr
+ xlibs.libXcursor libcap
];
};
in stdenv.mkDerivation rec {
name = "atom-${version}";
- version = "0.99.0";
+ version = "0.187.0";
src = fetchurl {
- url = https://github.com/hotice/webupd8/raw/master/atom-linux64-0.99.0~git20140525.tar.xz;
- sha256 = "55c2415c96e1182ae1517751cbea1db64e9962683b384cfe5e182aec10aebecd";
- name = "${name}.tar.xz";
- };
-
- iconsrc = fetchurl {
- url = https://raw.githubusercontent.com/atom/atom/master/resources/atom.png;
- sha256 = "66dc0b432eed7bcd738b7c1b194e539178a83d427c78f103041981f2b840e030";
- };
-
- desktopItem = makeDesktopItem {
- name = "atom";
- exec = "atom";
- icon = iconsrc;
- comment = "A hackable text editor for the 21st Century";
- desktopName = "Atom";
- genericName = "Text editor";
- categories = "Development;TextEditor";
+ url = "https://github.com/atom/atom/releases/download/v${version}/atom-amd64.deb";
+ sha256 = "0s6173dg5m52zc8kqwlgjn113d84cskrv9v29fb0nrvwvkv2xzmw";
+ name = "${name}.deb";
};
buildInputs = [ atomEnv makeWrapper ];
- phases = [ "installPhase" ];
+ phases = [ "installPhase" "fixupPhase" ];
installPhase = ''
- mkdir -p $out/share/atom
- mkdir -p $out/bin
- tar -C $out/share/atom -xvf $src
- patchelf --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
+ mkdir -p $out
+ ar p $src data.tar.gz | tar -C $out -xz ./usr
+ mv $out/usr/* $out/
+ rm -r $out/usr/
+ patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
$out/share/atom/atom
- patchelf --set-interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
- $out/share/atom/resources/app/apm/node_modules/atom-package-manager/bin/node
- makeWrapper $out/share/atom/atom $out/bin/atom \
+ patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+ $out/share/atom/resources/app/apm/bin/node
+ wrapProgram $out/bin/atom \
+ --prefix "LD_LIBRARY_PATH" : "${atomEnv}/lib:${atomEnv}/lib64"
+ wrapProgram $out/bin/apm \
--prefix "LD_LIBRARY_PATH" : "${atomEnv}/lib:${atomEnv}/lib64"
-
- # Create a desktop item.
- mkdir -p "$out/share/applications"
- cp "${desktopItem}"/share/applications/* "$out/share/applications/"
'';
meta = with stdenv.lib; {
diff --git a/pkgs/applications/editors/bluefish/default.nix b/pkgs/applications/editors/bluefish/default.nix
new file mode 100644
index 00000000000..25538df0384
--- /dev/null
+++ b/pkgs/applications/editors/bluefish/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, intltool, pkgconfig , gtk, libxml2
+, enchant, gucharmap, python
+}:
+
+stdenv.mkDerivation rec {
+ name = "bluefish-2.2.7";
+
+ src = fetchurl {
+ url = "mirror://sourceforge/bluefish/${name}.tar.bz2";
+ sha256 = "1psqx3ljz13ylqs4zkaxv9lv1hgzld6904kdp0alwx99p5rlnlr3";
+ };
+
+ buildInputs = [ intltool pkgconfig gtk libxml2
+ enchant gucharmap python ];
+
+ meta = with stdenv.lib; {
+ description = "A powerful editor targeted towards programmers and webdevelopers";
+ homepage = http://bluefish.openoffice.nl/;
+ license = licenses.gpl3Plus;
+ maintainers = [maintainers.vbgl];
+ platforms = platforms.all;
+ };
+}
diff --git a/pkgs/applications/editors/bvi/default.nix b/pkgs/applications/editors/bvi/default.nix
index e598fa19c5e..f3f44f769a9 100644
--- a/pkgs/applications/editors/bvi/default.nix
+++ b/pkgs/applications/editors/bvi/default.nix
@@ -1,18 +1,21 @@
{ stdenv, fetchurl, ncurses }:
-stdenv.mkDerivation {
- name = "bvi-1.3.2";
+stdenv.mkDerivation rec {
+ name = "bvi-${version}";
+ version = "1.4.0";
src = fetchurl {
- url = mirror://sourceforge/bvi/bvi-1.3.2.src.tar.gz;
- sha256 = "110wxqnyianqamxq4y53drqqxb9vp4k2fcvic45qggvlqkqhlfgz";
+ url = "mirror://sourceforge/bvi/${name}.src.tar.gz";
+ sha256 = "00pq9rv7s8inqxq2m3xshxi58691i3pxw9smibcrgh6768l3qnh1";
};
buildInputs = [ ncurses ];
- meta = {
+ meta = with stdenv.lib; {
description = "Hex editor with vim style keybindings";
homepage = http://bvi.sourceforge.net/download.html;
- license = stdenv.lib.licenses.gpl2;
+ license = licenses.gpl2;
+ maintainers = with maintainers; [ pSub ];
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/applications/editors/codeblocks/default.nix b/pkgs/applications/editors/codeblocks/default.nix
index 1bf4bb1f8e6..750234b6399 100644
--- a/pkgs/applications/editors/codeblocks/default.nix
+++ b/pkgs/applications/editors/codeblocks/default.nix
@@ -19,7 +19,7 @@ stdenv.mkDerivation rec {
enableParallelBuilding = true;
patches = [ ./writable-projects.patch ];
preConfigure = "substituteInPlace ./configure --replace /usr/bin/file ${file}/bin/file";
- postConfigure = optionalString stdenv.isLinux "substituteInPlace libtool --replace ldconfig ${stdenv.gcc.libc}/sbin/ldconfig";
+ postConfigure = optionalString stdenv.isLinux "substituteInPlace libtool --replace ldconfig ${stdenv.cc.libc}/sbin/ldconfig";
configureFlags = [ "--enable-pch=no" ]
++ optional contribPlugins "--with-contrib-plugins";
diff --git a/pkgs/applications/editors/eclipse/default.nix b/pkgs/applications/editors/eclipse/default.nix
index b32981ccb94..41be00bdb63 100644
--- a/pkgs/applications/editors/eclipse/default.nix
+++ b/pkgs/applications/editors/eclipse/default.nix
@@ -1,6 +1,7 @@
{ stdenv, fetchurl, makeDesktopItem, makeWrapper
, freetype, fontconfig, libX11, libXext, libXrender, zlib
, glib, gtk, libXtst, jre
+, webkitgtk2 ? null # for internal web browser
}:
assert stdenv ? glibc;
@@ -44,7 +45,7 @@ let
makeWrapper $out/eclipse/eclipse $out/bin/eclipse \
--prefix PATH : ${jre}/bin \
- --prefix LD_LIBRARY_PATH : ${glib}/lib:${gtk}/lib:${libXtst}/lib \
+ --prefix LD_LIBRARY_PATH : ${glib}/lib:${gtk}/lib:${libXtst}/lib${stdenv.lib.optionalString (webkitgtk2 != null) ":${webkitgtk2}/lib"} \
--add-flags "-configuration \$HOME/.eclipse/''${productId}_$productVersion/configuration"
# Create desktop item.
@@ -191,6 +192,23 @@ in {
sha256 = "0d6jlj7hwz8blx6csrlyi2h2prql0wckbh7ihwjmgclwpcpj84g6";
};
};
+
+ eclipse_cpp_44 = buildEclipse {
+ name = "eclipse-cpp-4.4";
+ description = "Eclipse IDE for C/C++ Developers";
+ src =
+ if stdenv.system == "x86_64-linux" then
+ fetchurl {
+ url = http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-linux-gtk-x86_64.tar.gz;
+ md5 = "b0a6ee33e8108a7ff4682ab911271b04";
+ }
+ else
+ fetchurl {
+ url = http://www.mirrorservice.org/sites/download.eclipse.org/eclipseMirror/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-linux-gtk.tar.gz;
+ md5 = "5000f93cecf6ef9af112f0df6e8c87f3";
+ };
+ };
+
eclipse_sdk_421 = buildEclipse {
name = "eclipse-sdk-4.2.1";
@@ -228,11 +246,11 @@ in {
description = "Eclipse Classic";
sources = {
"x86_64-linux" = fetchurl {
- url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.3.1-201309111000/eclipse-SDK-4.3.1-linux-gtk-x86_64.tar.gz;
+ url = http://archive.eclipse.org/eclipse/downloads/drops4/R-4.3.1-201309111000/eclipse-SDK-4.3.1-linux-gtk-x86_64.tar.gz;
sha256 = "0ncm56ylwxw9z8rk8ccgva68c2yr9yrf1kcr1zkgw6p87xh1yczd";
};
"i686-linux" = fetchurl {
- url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.3.1-201309111000/eclipse-SDK-4.3.1-linux-gtk.tar.gz;
+ url = http://archive.eclipse.org/eclipse/downloads/drops4/R-4.3.1-201309111000/eclipse-SDK-4.3.1-linux-gtk.tar.gz;
sha256 = "1zxsh838khny7mvl01h28xna6xdh01yi4mvls28zj22v0340lgsg";
};
};
@@ -243,14 +261,29 @@ in {
description = "Eclipse Classic";
sources = {
"x86_64-linux" = fetchurl {
- url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.4-201406061215/eclipse-SDK-4.4-linux-gtk-x86_64.tar.gz;
+ url = http://archive.eclipse.org/eclipse/downloads/drops4/R-4.4-201406061215/eclipse-SDK-4.4-linux-gtk-x86_64.tar.gz;
sha256 = "14hdkijsjq0hhzi9ijpwjjkhz7wm0pry86l3dniy5snlh3l5bsb2";
};
"i686-linux" = fetchurl {
- url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.4-201406061215/eclipse-SDK-4.4-linux-gtk.tar.gz;
+ url = http://archive.eclipse.org/eclipse/downloads/drops4/R-4.4-201406061215/eclipse-SDK-4.4-linux-gtk.tar.gz;
sha256 = "0hjc4zrsmik6vff851p0a4ydnx99840j2xrx8348kk6h0af8vx6z";
};
};
};
+ eclipse_sdk_442 = buildEclipse {
+ name = "eclipse-sdk-4.4.2";
+ description = "Eclipse Classic";
+ sources = {
+ "x86_64-linux" = fetchurl {
+ url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.4.2-201502041700/eclipse-SDK-4.4.2-linux-gtk-x86_64.tar.gz;
+ sha256 = "0g00alsixfaakmn4khr0m9fxvkrbhbg6qqfa27xr6a9np6gzg98l";
+
+ };
+ "i686-linux" = fetchurl {
+ url = http://download.eclipse.org/eclipse/downloads/drops4/R-4.4.2-201502041700/eclipse-SDK-4.4.2-linux-gtk.tar.gz;
+ sha256 = "9f4238ce9f887a1a57bbc6c6898e43357d14a6d74f59385327813c5e82aa735d";
+ };
+ };
+ };
}
diff --git a/pkgs/applications/editors/edbrowse/default.nix b/pkgs/applications/editors/edbrowse/default.nix
new file mode 100644
index 00000000000..8fdc198f45c
--- /dev/null
+++ b/pkgs/applications/editors/edbrowse/default.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchurl, spidermonkey_24, unzip, curl, pcre, readline, openssl }:
+stdenv.mkDerivation rec {
+ name = "edbrowse-3.5.2";
+ buildInputs = [ unzip curl pcre readline openssl spidermonkey_24 ];
+ preConfigure = ''
+ export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I${spidermonkey_24}/include/mozjs-24"
+ '';
+ installPhase = "installBin src/edbrowse";
+ src = fetchurl {
+ url = "http://the-brannons.com/edbrowse/${name}.zip";
+ sha256 = "5f1ac927d126b8c8fd411231cffa9eba5405013e64994e55e1864b2f85d52714";
+ };
+ meta = {
+ description = "Edbrowse, a Command Line Editor Browser";
+ longDescription = ''
+ Edbrowse is a combination editor, browser, and mail client that is 100% text based.
+ The interface is similar to /bin/ed, though there are many more features, such as editing multiple files simultaneously, and rendering html.
+ This program was originally written for blind users, but many sighted users have taken advantage of the unique scripting capabilities of this program, which can be found nowhere else.
+ A batch job, or cron job, can access web pages on the internet, submit forms, and send email, with no human intervention whatsoever.
+ edbrowse can also tap into databases through odbc. It was primarily written by Karl Dahlke.
+ '';
+ license = stdenv.lib.licenses.gpl1Plus;
+ homepage = http://the-brannons.com/edbrowse/;
+ maintainers = [ stdenv.lib.maintainers.schmitthenner ];
+ };
+}
diff --git a/pkgs/applications/editors/elvis/default.nix b/pkgs/applications/editors/elvis/default.nix
index e1d2ad69b1d..0850dd0e7be 100644
--- a/pkgs/applications/editors/elvis/default.nix
+++ b/pkgs/applications/editors/elvis/default.nix
@@ -35,6 +35,6 @@ stdenv.mkDerivation rec {
meta = {
homepage = http://elvis.vi-editor.org/;
description = "A vi clone for Unix and other operating systems";
- license = "free";
+ license = stdenv.lib.licenses.free;
};
}
diff --git a/pkgs/applications/editors/emacs-24/at-fdcwd.patch b/pkgs/applications/editors/emacs-24/at-fdcwd.patch
new file mode 100644
index 00000000000..1f99d4e1809
--- /dev/null
+++ b/pkgs/applications/editors/emacs-24/at-fdcwd.patch
@@ -0,0 +1,13 @@
+diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
+index 5cdb813..7a272e8 100644
+--- a/lib/careadlinkat.h
++++ b/lib/careadlinkat.h
+@@ -23,6 +23,8 @@
+ #include
+ #include
+
++#define AT_FDCWD -2
++
+ struct allocator;
+
+ /* Assuming the current directory is FD, get the symbolic link value
diff --git a/pkgs/applications/editors/emacs-24/builder.sh b/pkgs/applications/editors/emacs-24/builder.sh
index c472d2b1a64..984a61df6f3 100644
--- a/pkgs/applications/editors/emacs-24/builder.sh
+++ b/pkgs/applications/editors/emacs-24/builder.sh
@@ -5,13 +5,17 @@ source $stdenv/setup
# *our* versions, not the ones found in the system, as it would do by default.
# On other platforms, this appears to be unnecessary.
preConfigure() {
+ for i in Makefile.in ./src/Makefile.in ./lib-src/Makefile.in ./leim/Makefile.in; do
+ substituteInPlace $i --replace /bin/pwd pwd
+ done
+
case "${system}" in
x86_64-linux) glibclibdir=lib64 ;;
i686-linux) glibclibdir=lib ;;
*) return;
esac
- libc=$(cat ${NIX_GCC}/nix-support/orig-libc)
+ libc=$(cat ${NIX_CC}/nix-support/orig-libc)
echo "libc: $libc"
for i in src/s/*.h src/m/*.h; do
@@ -23,7 +27,9 @@ preConfigure() {
--replace /usr/lib/crti.o $libc/${glibclibdir}/crti.o \
--replace /usr/lib/crtn.o $libc/${glibclibdir}/crtn.o
done
+}
+preInstall () {
for i in Makefile.in ./src/Makefile.in ./lib-src/Makefile.in ./leim/Makefile.in; do
substituteInPlace $i --replace /bin/pwd pwd
done
diff --git a/pkgs/applications/editors/emacs-24/default.nix b/pkgs/applications/editors/emacs-24/default.nix
index 3bfee481c9c..83774206b5c 100644
--- a/pkgs/applications/editors/emacs-24/default.nix
+++ b/pkgs/applications/editors/emacs-24/default.nix
@@ -9,16 +9,19 @@ assert (libXft != null) -> libpng != null; # probably a bug
assert stdenv.isDarwin -> libXaw != null; # fails to link otherwise
stdenv.mkDerivation rec {
- name = "emacs-24.3";
+ name = "emacs-24.4";
builder = ./builder.sh;
src = fetchurl {
url = "mirror://gnu/emacs/${name}.tar.xz";
- sha256 = "1385qzs3bsa52s5rcncbrkxlydkw0ajzrvfxgv8rws5fx512kakh";
+ sha256 = "1zflm6ac34s6v166p58ilxrxbxjm0q2wfc25f8y0mjml1lbr3qs7";
};
- patches = [ ./darwin-new-sections.patch ];
+ patches = stdenv.lib.optionals stdenv.isDarwin [
+ ./darwin-new-sections.patch
+ ./at-fdcwd.patch
+ ];
buildInputs =
[ ncurses gconf libxml2 gnutls alsaLib pkgconfig texinfo ]
@@ -35,25 +38,14 @@ stdenv.mkDerivation rec {
[ "--with-x-toolkit=lucid" "--with-xft" ]
else
[ "--with-x=no" "--with-xpm=no" "--with-jpeg=no" "--with-png=no"
- "--with-gif=no" "--with-tiff=no" ] ) )
- # On NixOS, help Emacs find `crt*.o'.
- ++ stdenv.lib.optional (stdenv ? glibc)
- [ "--with-crt-dir=${stdenv.glibc}/lib" ];
+ "--with-gif=no" "--with-tiff=no" ] ) );
NIX_CFLAGS_COMPILE = stdenv.lib.optionalString (stdenv.isDarwin && withX)
"-I${cairo}/include/cairo";
postInstall = ''
- cat >$out/share/emacs/site-lisp/site-start.el <$out/share/emacs/site-lisp/site-start.el <
++#include
+
+
+ typedef struct __completion_Session_struct
diff --git a/pkgs/applications/editors/emacs-modes/emms/default.nix b/pkgs/applications/editors/emacs-modes/emms/default.nix
index a44be28399d..1e9843447d9 100644
--- a/pkgs/applications/editors/emacs-modes/emms/default.nix
+++ b/pkgs/applications/editors/emacs-modes/emms/default.nix
@@ -66,7 +66,7 @@ stdenv.mkDerivation rec {
license = stdenv.lib.licenses.gpl3Plus;
- maintainers = [ stdenv.lib.maintainers.ludo ];
+ maintainers = [ ];
platforms = stdenv.lib.platforms.unix;
broken = true;
};
diff --git a/pkgs/applications/editors/emacs-modes/ensime/default.nix b/pkgs/applications/editors/emacs-modes/ensime/default.nix
new file mode 100644
index 00000000000..d776103a662
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/ensime/default.nix
@@ -0,0 +1,22 @@
+{ stdenv, fetchurl, emacs, unzip, autoComplete, dash, s, scalaMode2, sbtMode }:
+
+stdenv.mkDerivation {
+ name = "emacs-ensime-2014-09-04";
+
+ src = fetchurl {
+ url = "https://github.com/ensime/ensime-emacs/archive/d3820a3f362975f6e14b817988ec07bfef2b4dad.zip";
+ sha256 = "0gwr0r92z2hh2x8g0hpxaar2vvfk1b91cp6v04gaasw0fvl5i7g5";
+ };
+
+ buildInputs = [ emacs unzip ];
+ propagatedUserEnvPkgs = [ autoComplete dash s scalaMode2 sbtMode ];
+
+ buildPhase = ''
+ emacs -L . -L ${autoComplete}/share/emacs/site-lisp --batch -f batch-byte-compile *.el
+ '';
+
+ installPhase = ''
+ install -d $out/share/emacs/site-lisp
+ install *.el *.elc $out/share/emacs/site-lisp
+ '';
+}
diff --git a/pkgs/applications/editors/emacs-modes/ess/default.nix b/pkgs/applications/editors/emacs-modes/ess/default.nix
index 46e20a58ee6..a2c73907115 100644
--- a/pkgs/applications/editors/emacs-modes/ess/default.nix
+++ b/pkgs/applications/editors/emacs-modes/ess/default.nix
@@ -1,11 +1,11 @@
{ stdenv, fetchurl, emacs, texinfo }:
stdenv.mkDerivation rec {
- name = "ess-13.09";
+ name = "ess-14.09";
src = fetchurl {
url = "http://ess.r-project.org/downloads/ess/${name}.tgz";
- sha256 = "1lki3vb6p7cw98zqq0gaia68flpqrjkd6dcl85fs0cc8qf55yqnh";
+ sha256 = "0wa507jfmq3k7x0vigd2yzb4j2190ix4wnnpv7ql4bjy0vfvmwdn";
};
buildInputs = [ emacs texinfo ];
diff --git a/pkgs/applications/editors/emacs-modes/flycheck/default.nix b/pkgs/applications/editors/emacs-modes/flycheck/default.nix
new file mode 100644
index 00000000000..98eab4d477c
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/flycheck/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, fetchFromGitHub, emacs, let-alist, dash, texinfo }:
+
+stdenv.mkDerivation {
+ name = "flycheck-0.22-64-g90dbc2d";
+
+ src = fetchFromGitHub {
+ owner = "flycheck";
+ repo = "flycheck";
+ rev = "90dbc2d";
+ sha256 = "08bg4jps6hjldbcrvqarrwdv4xzirm5pns5s0331wm0sc47yvbli";
+ };
+
+ buildInputs = [ emacs texinfo ];
+
+ buildPhase = ''
+ emacs -L ${let-alist}/share/emacs/site-lisp -L ${dash}/share/emacs/site-lisp --batch -f batch-byte-compile flycheck.el
+ makeinfo --force --no-split -o doc/flycheck.info doc/flycheck.texi
+ '';
+
+ installPhase = ''
+ mkdir -p $out/share/emacs/site-lisp $out/share/info
+ mv flycheck.el flycheck.elc $out/share/emacs/site-lisp/
+ mv "doc/"*.info $out/share/info/
+ '';
+
+ meta = {
+ homepage = "https://github.com/magit/git-modes";
+ description = "Emacs modes for various Git-related files";
+ license = stdenv.lib.licenses.gpl3Plus;
+ maintainers = with stdenv.lib.maintainers; [ simons ];
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/git-modes/default.nix b/pkgs/applications/editors/emacs-modes/git-modes/default.nix
new file mode 100644
index 00000000000..8a2ca6eb909
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/git-modes/default.nix
@@ -0,0 +1,29 @@
+{ stdenv, fetchFromGitHub, emacs }:
+
+let
+ version = "0.15.0-8-g4e10851";
+in
+stdenv.mkDerivation {
+ name = "git-modes-${version}";
+
+ src = fetchFromGitHub {
+ owner = "magit";
+ repo = "git-modes";
+ rev = "4e10851843145e0c05fc665683d3b487a57ad114";
+ sha256 = "13j794a2p4ql9dnw2z0c1m0ybclxsicbk8cmmfqcchs4ygiyc6ag";
+ };
+
+ buildInputs = [ emacs ];
+
+ installPhase = ''
+ mkdir -p $out/share/emacs/site-lisp
+ mv *.el *.elc $out/share/emacs/site-lisp/
+ '';
+
+ meta = {
+ homepage = "https://github.com/magit/git-modes";
+ description = "Emacs modes for various Git-related files";
+ license = stdenv.lib.licenses.gpl3Plus;
+ maintainers = with stdenv.lib.maintainers; [ simons ];
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/haskell/default.nix b/pkgs/applications/editors/emacs-modes/haskell/default.nix
index 3f4b93dc638..7f4373c41ba 100644
--- a/pkgs/applications/editors/emacs-modes/haskell/default.nix
+++ b/pkgs/applications/editors/emacs-modes/haskell/default.nix
@@ -1,18 +1,25 @@
{ stdenv, fetchurl, emacs, texinfo }:
-stdenv.mkDerivation rec {
- name = "haskell-mode-13.10";
+let
+ version = "13.10";
+in
+stdenv.mkDerivation {
+ name = "haskell-mode-${version}";
src = fetchurl {
- url = "https://github.com/haskell/haskell-mode/archive/v13.10.tar.gz";
+ url = "https://github.com/haskell/haskell-mode/archive/v${version}.tar.gz";
sha256 = "0hcg7wpalcdw8j36m8vd854zrrgym074r7m903rpwfrhx9mlg02b";
};
buildInputs = [ emacs texinfo ];
+ makeFlags = "VERSION=${version} GIT_VERSION=${version}";
+
installPhase = ''
- mkdir -p "$out/share/emacs/site-lisp"
- cp *.el *.elc *.hs "$out/share/emacs/site-lisp/"
+ mkdir -p $out/share/emacs/site-lisp
+ cp *.el *.elc *.hs $out/share/emacs/site-lisp/
+ mkdir -p $out/share/info
+ cp -v *.info* $out/share/info/
'';
meta = {
diff --git a/pkgs/applications/editors/emacs-modes/haskell/git.nix b/pkgs/applications/editors/emacs-modes/haskell/git.nix
new file mode 100644
index 00000000000..20de1cae4d3
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/haskell/git.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchFromGitHub, emacs, texinfo }:
+
+let
+ version = "13.10-361-gfa09425"; # git describe --tags
+in
+stdenv.mkDerivation {
+ name = "haskell-mode-${version}";
+
+ src = fetchFromGitHub {
+ owner = "haskell";
+ repo = "haskell-mode";
+ rev = "v${version}";
+ sha256 = "1bq4gddzwjy2w1hbsmwxcamcy87amz7ksy1vmpwg0qij88fk4av9";
+ };
+
+ buildInputs = [ emacs texinfo ];
+
+ makeFlags = "VERSION=v${version} GIT_VERSION=v${version}";
+
+ installPhase = ''
+ mkdir -p $out/share/emacs/site-lisp
+ cp *.el *.elc *.hs $out/share/emacs/site-lisp/
+ mkdir -p $out/share/info
+ cp -v *.info* $out/share/info/
+ '';
+
+ # The test suite must run *after* copying the generated files to $out
+ # because "make check" implies "make clean".
+ doInstallCheck = true;
+ installCheckTarget = "check";
+
+ meta = {
+ homepage = "http://github.com/haskell/haskell-mode";
+ description = "Haskell mode for Emacs";
+
+ platforms = stdenv.lib.platforms.unix;
+ maintainers = [ stdenv.lib.maintainers.simons ];
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/hsc3/default.nix b/pkgs/applications/editors/emacs-modes/hsc3/default.nix
new file mode 100644
index 00000000000..150bd3593fd
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/hsc3/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchurl, emacs }:
+
+# this package installs the emacs-mode which
+# resides in the hsc3 sources.
+
+let version = "0.15";
+
+in stdenv.mkDerivation {
+ name = "hsc3-mode-${version}";
+ src = fetchurl {
+ url = http://hackage.haskell.org/package/hsc3-0.15/hsc3-0.15.tar.gz;
+ sha256 = "2f3b15655419cf8ebe25ab1c6ec22993b2589b4ffca7c3a75ce478ca78a0bde6";
+ };
+
+ buildInputs = [ emacs ];
+
+ installPhase = ''
+ mkdir -p "$out/share/emacs/site-lisp"
+ cp "emacs/hsc3.el" "$out/share/emacs/site-lisp"
+ '';
+
+ meta = {
+ homepage = http://rd.slavepianos.org/?t=hsc3;
+ description = "hsc3 mode package for Emacs";
+ platforms = stdenv.lib.platforms.unix;
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/icicles/default.nix b/pkgs/applications/editors/emacs-modes/icicles/default.nix
new file mode 100644
index 00000000000..820e959a357
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/icicles/default.nix
@@ -0,0 +1,42 @@
+{ stdenv, fetchurl, emacs }:
+
+let
+ modules = [
+ { name = "icicles.el"; sha256 = "175g8w620vy73pp3zyasfjspgljk6g0lki71kdnvw5z88w3s9d1n"; }
+ { name = "icicles-chg.el"; sha256 = "1bx5xdhirvnrjqk4pk0sjp9bpj1syymsjnckklsw04gv6y0x8zik"; }
+ { name = "icicles-cmd1.el"; sha256 = "1ff0mndin9zxrswwwq3a7b1s879rr6gy8rzxanr7kxg1ppciafad"; }
+ { name = "icicles-cmd2.el"; sha256 = "1a44l86jacp9nsy4z260azz6y672drjw3w5a0jsc8w26fgsrnx1k"; }
+ { name = "icicles-doc1.el"; sha256 = "0s3r4z3y06hd1nxp18wd0b8b88z2a7ryy0j8sx5fzibbmp58ars1"; }
+ { name = "icicles-doc2.el"; sha256 = "0c10jg91qxyrg1zwiyi4m57dbw3yf43jdrpi4nnby3pkzh6i37ic"; }
+ { name = "icicles-face.el"; sha256 = "0n0vcbhwgd2lyj7anq1zpwja28xry018qxbm8sprxkh6y3vlw8d2"; }
+ { name = "icicles-fn.el"; sha256 = "1i10593a7hp465bxd86h7h7gwrdyqxx0d13in53z4jnab8icp3d4"; }
+ { name = "icicles-mac.el"; sha256 = "1piq0jk8nz0hz9wwci7dkxnfxscdpygjzpj5zg3310vs22l7rrsz"; }
+ { name = "icicles-mcmd.el"; sha256 = "0c4325yp84i46605nlxmjm6n0f4fh69shsihvd0wb9ryg0a8qa65"; }
+ { name = "icicles-mode.el"; sha256 = "069wx5clqpsq2c9aavgd9xihvlad3g00iwwrc3cpl47v64dvlipq"; }
+ { name = "icicles-opt.el"; sha256 = "16487l3361ca8l6il2c0z892843sc5l9v4gr7lx5fxbmrlsswvvn"; }
+ { name = "icicles-var.el"; sha256 = "1a9cwxpi10x44fngxa7qnrg8hqfvdjb8s8k47gnn1rbh63blkkry"; }
+ ];
+
+ forAll = f: map f modules;
+in
+stdenv.mkDerivation {
+ name = "icicles-2014-11-06";
+
+ srcs = forAll ({name, sha256}: fetchurl { url = "http://www.emacswiki.org/emacs-en/download/${name}"; inherit sha256; });
+
+ buildInputs = [ emacs ];
+
+ unpackPhase = "for m in $srcs; do cp $m $(echo $m | cut -d- -f2-); done";
+
+ buildPhase = "emacs --batch -L . -f batch-byte-compile *.el";
+
+ installPhase = "mkdir -p $out/share/emacs/site-lisp; cp *.el *.elc $out/share/emacs/site-lisp/";
+
+ meta = {
+ homepage = "http://www.emacswiki.org/emacs/Icicles";
+ description = "Enhance Emacs minibuffer input with cycling and powerful completion.";
+ license = stdenv.lib.licenses.gpl2Plus;
+
+ maintainers = with stdenv.lib.maintainers; [ simons ];
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/idris/default.nix b/pkgs/applications/editors/emacs-modes/idris/default.nix
index 4e9d1cfd77c..a631939b55c 100644
--- a/pkgs/applications/editors/emacs-modes/idris/default.nix
+++ b/pkgs/applications/editors/emacs-modes/idris/default.nix
@@ -3,11 +3,11 @@
stdenv.mkDerivation rec {
name = "${pname}-${version}";
pname = "idris-mode";
- version = "0.9.14";
+ version = "0.9.15";
src = fetchurl {
url = "https://github.com/idris-hackers/${pname}/archive/${version}.tar.gz";
- sha256 = "1qlkbf14mcibp6h5r84fp5xdjspyaw1xdmnkmaxbypwjhhjg4s83";
+ sha256 = "0ag7qqsv64rifk9ncdxv4gyylfbw6c8y2wq610l4pabqv2qrlh9r";
};
buildInputs = [ emacs ];
diff --git a/pkgs/applications/editors/emacs-modes/js2/default.nix b/pkgs/applications/editors/emacs-modes/js2/default.nix
index 00123bfc8c7..ba9fb4f8d6f 100644
--- a/pkgs/applications/editors/emacs-modes/js2/default.nix
+++ b/pkgs/applications/editors/emacs-modes/js2/default.nix
@@ -1,12 +1,12 @@
{ stdenv, fetchgit, emacs }:
stdenv.mkDerivation {
- name = "js2-mode-0-20140114";
+ name = "js2-mode-0-20141118";
src = fetchgit {
url = "git://github.com/mooz/js2-mode.git";
- rev = "b250efaad886dd07b8c69d4573425d095c6652e2";
- sha256 = "30e61e7d364e9175d408bdaf57fda886a4eea22cf5cbd97abb5c307c52b05918";
+ rev = "3abcd90ddc2f446ddf0fb874dd79ba870c26ad2d";
+ sha256 = "c0aaab4eeb8d60cfd5c382c3e30d4725e5ec492720d573e663ea69ee43aa73a8";
};
buildInputs = [ emacs ];
diff --git a/pkgs/applications/editors/emacs-modes/let-alist/default.nix b/pkgs/applications/editors/emacs-modes/let-alist/default.nix
new file mode 100644
index 00000000000..863e9f95d95
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/let-alist/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchurl, emacs }:
+
+stdenv.mkDerivation rec {
+ name = "let-alist-1.0.3";
+
+ src = fetchurl {
+ url = "http://elpa.gnu.org/packages/let-alist-1.0.3.el";
+ sha256 = "12n1cmjc7hzyy0jmsdxqz1hqzg4ri4nvvi0p9mw1d6v44xzfm0mx";
+ };
+
+ buildInputs = [ emacs ];
+
+ unpackPhase = "cp -v ${src} let-alist.el";
+ buildPhase = "emacs --batch -f batch-byte-compile let-alist.el";
+
+ installPhase = ''
+ mkdir -p $out/share/emacs/site-lisp
+ mv -v *.el *.elc $out/share/emacs/site-lisp/
+ '';
+
+ meta = {
+ homepage = "http://elpa.gnu.org/packages/let-alist.html";
+ description = "Easily let-bind values of an assoc-list by their names";
+ license = stdenv.lib.licenses.gpl3Plus;
+ maintainers = with stdenv.lib.maintainers; [ simons ];
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/magit/default.nix b/pkgs/applications/editors/emacs-modes/magit/default.nix
index 076caf5235b..676a86985f8 100644
--- a/pkgs/applications/editors/emacs-modes/magit/default.nix
+++ b/pkgs/applications/editors/emacs-modes/magit/default.nix
@@ -1,25 +1,32 @@
-{ stdenv, fetchurl, emacs, texinfo }:
+{ stdenv, fetchFromGitHub, emacs, texinfo, gitModes, git }:
-let
- version = "1.2.0";
-in
stdenv.mkDerivation rec {
- name = "magit-${version}";
+ name = "magit-90141025";
- src = fetchurl {
- url = "https://github.com/downloads/magit/magit/${name}.tar.gz";
- sha256 = "1a8vvilhd5y5vmlpsh194qpl4qlg0a1brylfscxcacpfp0cmhlzg";
+ src = fetchFromGitHub {
+ owner = "magit";
+ repo = "magit";
+ rev = "50c08522c8a3c67e0f3b821fe4df61e8bd456ff9";
+ sha256 = "0mzyx72pidzvla1x2qszn3c60n2j0n8i5k875c4difvd1n4p0vsk";
};
- buildInputs = [ emacs texinfo ];
+ buildInputs = [ emacs texinfo git ];
+ propagatedUserEnvPkgs = [ gitModes ];
- configurePhase = "makeFlagsArray=( PREFIX=$out SYSCONFDIR=$out/etc )";
+ configurePhase = ''
+ makeFlagsArray=(
+ PREFIX="$out"
+ EFLAGS="-L ${gitModes}/share/emacs/site-lisp"
+ lispdir="$out/share/emacs/site-lisp"
+ )
+ '';
+
+ doCheck = true;
+ checkTarget = "test";
- # Add (require 'magit-site-init) to your ~/.emacs file to set-up magit mode.
postInstall = ''
- mv $out/etc/emacs/site-start.d/50magit.el $out/share/emacs/site-lisp/magit-site-init.el
- sed -i -e 's|50magit|magit-site-init|' $out/share/emacs/site-lisp/magit-site-init.el
- rmdir $out/etc/emacs/site-start.d $out/etc/emacs $out/etc
+ mkdir -p $out/bin
+ mv "bin/"* $out/bin/
'';
meta = {
@@ -39,7 +46,6 @@ stdenv.mkDerivation rec {
save you from learning Git itself.
'';
- platforms = stdenv.lib.platforms.all;
maintainers = with stdenv.lib.maintainers; [ simons ];
};
}
diff --git a/pkgs/applications/editors/emacs-modes/nyan-mode/default.nix b/pkgs/applications/editors/emacs-modes/nyan-mode/default.nix
new file mode 100644
index 00000000000..ab94dbae950
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/nyan-mode/default.nix
@@ -0,0 +1,31 @@
+{trivialBuild, fetchFromGitHub}:
+
+trivialBuild rec {
+ pname = "nyan-mode";
+ version = "20150128";
+
+ src = fetchFromGitHub {
+ owner = "TeMPOraL";
+ repo = pname;
+ rev = "41faa2c809da7b2cb3e6f8fadefae3f338ced3f2";
+ sha256 = "1idaac7sjc8hhbf5zif61ncg1pvg28c0qfihavdx61albww0ll7f";
+ };
+
+ patches = [ ./directory.patch ];
+
+ preBuild = ''
+ substituteInPlace nyan-mode.el \
+ --replace "@OUT@" "$out/"
+ '';
+
+ postInstall = ''
+ cp -r img $out
+ cp -r mus $out
+ '';
+
+ meta = {
+ description = "An analog indicator of the position in the buffer";
+ homepage = https://github.com/TeMPOraL/nyan-mode/;
+ license = "GPLv3+";
+ };
+}
diff --git a/pkgs/applications/editors/emacs-modes/nyan-mode/directory.patch b/pkgs/applications/editors/emacs-modes/nyan-mode/directory.patch
new file mode 100644
index 00000000000..b471531ec34
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/nyan-mode/directory.patch
@@ -0,0 +1,13 @@
+diff --git a/nyan-mode.el b/nyan-mode.el
+index 939a25a..3d0b983 100644
+--- a/nyan-mode.el
++++ b/nyan-mode.el
+@@ -106,7 +106,7 @@ This can be t or nil."
+ :group 'nyan)
+
+
+-(defconst +nyan-directory+ (file-name-directory (or load-file-name buffer-file-name)))
++(defconst +nyan-directory+ "@OUT@")
+
+ (defconst +nyan-cat-size+ 3)
+
diff --git a/pkgs/applications/editors/emacs-modes/org/default.nix b/pkgs/applications/editors/emacs-modes/org/default.nix
index d5a7b0ded8a..c7ad1c7049b 100644
--- a/pkgs/applications/editors/emacs-modes/org/default.nix
+++ b/pkgs/applications/editors/emacs-modes/org/default.nix
@@ -2,11 +2,11 @@
, texLiveAggregationFun }:
stdenv.mkDerivation rec {
- name = "org-8.2.7c";
+ name = "org-8.2.10";
src = fetchurl {
url = "http://orgmode.org/${name}.tar.gz";
- sha256 = "0qqf58xqw1kkgjxm9z40s6h7xd209rx3933klla22lryv3yclc1k";
+ sha256 = "1xm8n8zwr3676rl4pd32k61rd7rimlihhrw5a7r4z7r154c4a2fz";
};
buildInputs = [ emacs ];
diff --git a/pkgs/applications/editors/emacs-modes/proofgeneral/4.3pre.nix b/pkgs/applications/editors/emacs-modes/proofgeneral/4.3pre.nix
index 3a492dc0c7f..96d7619d387 100644
--- a/pkgs/applications/editors/emacs-modes/proofgeneral/4.3pre.nix
+++ b/pkgs/applications/editors/emacs-modes/proofgeneral/4.3pre.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl, emacs, texinfo, texLive, perl, which, automake }:
+{ stdenv, fetchurl, emacs, texinfo, texLive, perl, which, automake, enableDoc ? false }:
stdenv.mkDerivation (rec {
name = "ProofGeneral-4.3pre131011";
@@ -10,7 +10,7 @@ stdenv.mkDerivation (rec {
sourceRoot = name;
- buildInputs = [ emacs texinfo texLive perl which ];
+ buildInputs = [ emacs texinfo perl which ] ++ stdenv.lib.optional enableDoc texLive;
prePatch =
'' sed -i "Makefile" \
@@ -25,15 +25,20 @@ stdenv.mkDerivation (rec {
sed -i '96d' doc/ProofGeneral.texi
'';
+ patches = [ ./pg.patch ];
+
preBuild = ''
make clean;
'';
installPhase =
+ if enableDoc
+ then
# Copy `texinfo.tex' in the right place so that `texi2pdf' works.
'' cp -v "${automake}/share/"automake-*/texinfo.tex doc
make install install-doc
- '';
+ ''
+ else "make install";
meta = {
description = "Proof General, an Emacs front-end for proof assistants";
@@ -42,7 +47,7 @@ stdenv.mkDerivation (rec {
interactive theorem provers), based on the customizable text editor Emacs.
'';
homepage = http://proofgeneral.inf.ed.ac.uk;
- license = "GPLv2+";
+ license = stdenv.lib.licenses.gpl2Plus;
platforms = stdenv.lib.platforms.unix; # arbitrary choice
};
})
diff --git a/pkgs/applications/editors/emacs-modes/proofgeneral/pg.patch b/pkgs/applications/editors/emacs-modes/proofgeneral/pg.patch
new file mode 100644
index 00000000000..c733911118d
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/proofgeneral/pg.patch
@@ -0,0 +1,16 @@
+diff -r c7d8bfff4c0a bin/proofgeneral
+--- a/bin/proofgeneral Sat Sep 27 02:25:15 2014 +0100
++++ b/bin/proofgeneral Sat Sep 27 02:28:16 2014 +0100
+@@ -73,11 +73,7 @@
+
+ # Try to find Proof General directory
+ if [ -z "$PGHOME" ] || [ ! -d "$PGHOME" ]; then
+- # default relative to this script, otherwise PGHOMEDEFAULT
+- MYDIR="`readlink --canonicalize "$0" | sed -ne 's,/bin/proofgeneral$,,p'`"
+- if [ -d "$MYDIR" ]; then
+- PGHOME="$MYDIR"
+- elif [ -d "$PGHOMEDEFAULT" ]; then
++ if [ -d "$PGHOMEDEFAULT" ]; then
+ PGHOME="$PGHOMEDEFAULT"
+ else
+ echo "Cannot find the Proof General lisp files: Set PGHOME or use --pghome."
diff --git a/pkgs/applications/editors/emacs-modes/rainbow-delimiters/default.nix b/pkgs/applications/editors/emacs-modes/rainbow-delimiters/default.nix
new file mode 100644
index 00000000000..2b4223cdc1f
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/rainbow-delimiters/default.nix
@@ -0,0 +1,23 @@
+{stdenv, fetchurl, emacs}:
+
+let version = "1.3.13";
+
+in stdenv.mkDerivation {
+ name = "emacs-rainbow-delimiters-${version}";
+
+ src = fetchurl {
+ url = "https://github.com/jlr/rainbow-delimiters/archive/${version}.tar.gz";
+ sha256 = "075j3nsk4jm0rs5671n28c1wksrfbvpl9a4f89kzcd7sk1h6ncvl";
+ };
+
+ buildInputs = [ emacs ];
+
+ buildPhase = ''
+ emacs -L . --batch -f batch-byte-compile *.el
+ '';
+
+ installPhase = ''
+ install -d $out/share/emacs/site-lisp
+ install *.el *.elc $out/share/emacs/site-lisp
+ '';
+}
diff --git a/pkgs/applications/editors/emacs-modes/s/default.nix b/pkgs/applications/editors/emacs-modes/s/default.nix
new file mode 100644
index 00000000000..b818348939e
--- /dev/null
+++ b/pkgs/applications/editors/emacs-modes/s/default.nix
@@ -0,0 +1,23 @@
+{stdenv, fetchurl, emacs}:
+
+let version = "1.9.0";
+
+in stdenv.mkDerivation {
+ name = "emacs-s-${version}";
+
+ src = fetchurl {
+ url = "https://github.com/magnars/s.el/archive/${version}.tar.gz";
+ sha256 = "1gah2k577gvnmxlpw7zrz0jr571vghzhdv2hbgchlgah07czd091";
+ };
+
+ buildInputs = [ emacs ];
+
+ buildPhase = ''
+ emacs -L . --batch -f batch-byte-compile *.el
+ '';
+
+ installPhase = ''
+ install -d $out/share/emacs/site-lisp
+ install *.el *.elc $out/share/emacs/site-lisp
+ '';
+}
diff --git a/pkgs/applications/editors/emacs-modes/scala-mode/v2.nix b/pkgs/applications/editors/emacs-modes/scala-mode/v2.nix
index 13d3f4b00d1..75861b0a988 100644
--- a/pkgs/applications/editors/emacs-modes/scala-mode/v2.nix
+++ b/pkgs/applications/editors/emacs-modes/scala-mode/v2.nix
@@ -2,11 +2,11 @@
stdenv.mkDerivation {
- name = "scala-mode2-2014-06-05";
+ name = "scala-mode2-2014-07-01";
src = fetchurl {
- url = "https://github.com/hvesalai/scala-mode2/archive/af2dc30226c890ff7d49d727450f8006b90781df.zip";
- sha256 = "1jj08li9lfg5291jzj170wa3cmyf3g2a0j80cy5307l0mdawp9vx";
+ url = "https://github.com/hvesalai/scala-mode2/archive/c154f1623f4696d26e1c88d19170e67bf6825837.zip";
+ sha256 = "0fyxdpwz55n4c87v4ijqlbv6w1rybg5qrgsc40f6bs6sd747scy5";
};
buildInputs = [ unzip emacs ];
diff --git a/pkgs/applications/editors/emacs-modes/structured-haskell-mode/default.nix b/pkgs/applications/editors/emacs-modes/structured-haskell-mode/default.nix
index a9c2478d451..b8838fac980 100644
--- a/pkgs/applications/editors/emacs-modes/structured-haskell-mode/default.nix
+++ b/pkgs/applications/editors/emacs-modes/structured-haskell-mode/default.nix
@@ -2,8 +2,8 @@
cabal.mkDerivation (self: {
pname = "structured-haskell-mode";
- version = "1.0.3";
- sha256 = "0axmw8bj51q8v0wd4jp6giw9dnv0mp7kp8yd16s4nm4hcqgrh5h2";
+ version = "1.0.4";
+ sha256 = "1402wx27py7292ad7whsb13ywv71k36501jpfrn2p0v7knzknj8z";
isLibrary = false;
isExecutable = true;
buildDepends = [ haskellSrcExts haskellMode ];
diff --git a/pkgs/applications/editors/emacs-modes/tuareg/default.nix b/pkgs/applications/editors/emacs-modes/tuareg/default.nix
index 3fd592f3dba..364daed439d 100644
--- a/pkgs/applications/editors/emacs-modes/tuareg/default.nix
+++ b/pkgs/applications/editors/emacs-modes/tuareg/default.nix
@@ -1,15 +1,15 @@
-{ stdenv, fetchurl, emacs }:
+{ stdenv, fetchzip, emacs }:
# this package installs the emacs-mode which
# resides in the ocaml compiler sources.
-let version = "2.0.6";
+let version = "2.0.9";
in stdenv.mkDerivation {
name = "tuareg-mode-${version}";
- src = fetchurl {
- url = https://forge.ocamlcore.org/frs/download.php/882/tuareg-2.0.6.tar.gz;
- sha256 = "ea79ac24623b82ab8047345f8504abca557a537e639d16ce1ac3e5b27f5b1189";
+ src = fetchzip {
+ url = "https://github.com/ocaml/tuareg/releases/download/${version}/tuareg-${version}.tar.gz";
+ sha256 = "1rd7ai1wn476zfkkxv2xk72bbzi4d9c17gngd35882q4b5vzp756";
};
buildInputs = [ emacs ];
@@ -20,8 +20,9 @@ in stdenv.mkDerivation {
'';
meta = {
- homepage = http://caml.inria.fr;
+ homepage = https://github.com/ocaml/tuareg;
description = "OCaml mode package for Emacs";
platforms = stdenv.lib.platforms.unix;
+ license = stdenv.lib.licenses.gpl2Plus;
};
}
diff --git a/pkgs/applications/editors/emacs-modes/writegood/default.nix b/pkgs/applications/editors/emacs-modes/writegood/default.nix
index d196c3fee80..6d0631a4cb8 100644
--- a/pkgs/applications/editors/emacs-modes/writegood/default.nix
+++ b/pkgs/applications/editors/emacs-modes/writegood/default.nix
@@ -1,12 +1,12 @@
{stdenv, fetchurl, emacs}:
-let version = "2.0";
+let version = "2.0.2";
in stdenv.mkDerivation {
name = "writegood-mode-${version}";
src = fetchurl {
url = "https://github.com/bnbeckwith/writegood-mode/archive/v${version}.tar.gz";
- sha256 = "0wf7bj9d00ggy3xigym885a3njfr98i3aqrrawf8x6lgbfc56dgp";
+ sha256 = "1ilbqj24vzpfh9n1wph7idj0914ga290jkpv9kr1pff3a0v5hf6k";
};
buildInputs = [ emacs ];
diff --git a/pkgs/applications/editors/flpsed/default.nix b/pkgs/applications/editors/flpsed/default.nix
index d9f62216fac..640b06d2807 100644
--- a/pkgs/applications/editors/flpsed/default.nix
+++ b/pkgs/applications/editors/flpsed/default.nix
@@ -1,11 +1,11 @@
{stdenv, fetchurl, fltk13, ghostscript}:
stdenv.mkDerivation {
- name = "flpsed-0.7.1";
+ name = "flpsed-0.7.2";
src = fetchurl {
- url = "http://www.ecademix.com/JohannesHofmann/flpsed-0.7.1.tar.gz";
- sha256 = "16i3mjc1cdx2wiwfhnv3z2ywmjma9785vwl3l31izx9l51w7ngj3";
+ url = "http://www.ecademix.com/JohannesHofmann/flpsed-0.7.2.tar.gz";
+ sha256 = "1132nlganr6x4f4lzcp9l0xihg2ky1l7xk8vq7r2l2qxs97vbif8";
};
buildInputs = [ fltk13 ghostscript ];
@@ -15,5 +15,6 @@ stdenv.mkDerivation {
homepage = "http://http://flpsed.org/flpsed.html";
license = stdenv.lib.licenses.gpl3;
platforms = stdenv.lib.platforms.mesaPlatforms;
+ maintainers = with stdenv.lib.maintainers; [ fuuzetsu ];
};
}
diff --git a/pkgs/applications/editors/focuswriter/default.nix b/pkgs/applications/editors/focuswriter/default.nix
new file mode 100644
index 00000000000..bc9163e63cb
--- /dev/null
+++ b/pkgs/applications/editors/focuswriter/default.nix
@@ -0,0 +1,25 @@
+{stdenv, fetchurl, qt4, pkgconfig, hunspell}:
+
+stdenv.mkDerivation rec {
+ name = "focuswriter-${version}";
+ version = "1.5.3";
+
+ src = fetchurl {
+ url = http://gottcode.org/focuswriter/focuswriter-1.5.3-src.tar.bz2;
+ sha256 = "1i58jxbiy95ijf81g8c3gwxhcg3irzssna3wv7vhrd57g4lcfj0w";
+ };
+
+ buildInputs = [ qt4 pkgconfig hunspell ];
+
+ configurePhase = "qmake PREFIX=/";
+
+ installPhase = "make install INSTALL_ROOT=$out";
+
+ meta = {
+ description = "Simple, distraction-free writing environment";
+ license = stdenv.lib.licenses.gpl2;
+ maintainers = [ stdenv.lib.maintainers.madjar ];
+ platforms = stdenv.lib.platforms.all;
+ homepage = "http://gottcode.org/focuswriter/";
+ };
+}
diff --git a/pkgs/applications/editors/geany/default.nix b/pkgs/applications/editors/geany/default.nix
index d7ed048cdaa..8d4002c9ef8 100644
--- a/pkgs/applications/editors/geany/default.nix
+++ b/pkgs/applications/editors/geany/default.nix
@@ -1,7 +1,7 @@
-{ stdenv, fetchurl, gtk2, which, pkgconfig, intltool }:
+{ stdenv, fetchurl, gtk2, which, pkgconfig, intltool, file }:
let
- version = "1.23.1";
+ version = "1.24.1";
in
stdenv.mkDerivation rec {
@@ -9,15 +9,17 @@ stdenv.mkDerivation rec {
src = fetchurl {
url = "http://download.geany.org/${name}.tar.bz2";
- sha256 = "1bcgjxywggsljs9kq22kr9xpzrq5xr7pb9d1b71rwryqb5pb25c8";
+ sha256 = "0cwci8876dpgcn60dfvjlciqr8x68iv86psjj148grhzn3chbdbz";
};
- buildInputs = [ gtk2 which pkgconfig intltool ];
+ buildInputs = [ gtk2 which pkgconfig intltool file ];
doCheck = true;
enableParallelBuilding = true;
+ patchPhase = "patchShebangs .";
+
# This file should normally require a gtk-update-icon-cache -q /usr/share/icons/hicolor command
# It have no reasons to exist in a redistribuable package
postInstall = "rm $out/share/icons/hicolor/icon-theme.cache";
diff --git a/pkgs/applications/editors/gobby/default.nix b/pkgs/applications/editors/gobby/default.nix
index 5ef19874531..c023da0bc95 100644
--- a/pkgs/applications/editors/gobby/default.nix
+++ b/pkgs/applications/editors/gobby/default.nix
@@ -9,10 +9,10 @@ let
in stdenv.mkDerivation rec {
- name = "gobby-0.4.94";
+ name = "gobby-0.5.0";
src = fetchurl {
url = "http://releases.0x539.de/gobby/${name}.tar.gz";
- sha256 = "b9798808447cd94178430f0fb273d0e45d0ca30ab04560e3790bac469e03bb00";
+ sha256 = "165x0r668ma5blziisvbr8qig3jw9hf7i6w8r7wwvz3wsac3bswc";
};
buildInputs = [ pkgconfig gtkmm gsasl gtksourceview libxmlxx libinf intltool ]
diff --git a/pkgs/applications/editors/idea/default.nix b/pkgs/applications/editors/idea/default.nix
index caa9523af6f..0d6851a79e8 100644
--- a/pkgs/applications/editors/idea/default.nix
+++ b/pkgs/applications/editors/idea/default.nix
@@ -1,105 +1,319 @@
{ stdenv, fetchurl, makeDesktopItem, makeWrapper, patchelf, p7zip, jdk
-, coreutils, gnugrep, which, git
+, coreutils, gnugrep, which, git, python, unzip, androidsdk
}:
assert stdenv.isLinux;
let
- buildIdea =
- { name, version, build, src, description, longDescription, license }:
+ mkIdeaProduct = with stdenv.lib;
+ { name, product, version, build, src, meta }:
- stdenv.mkDerivation rec {
- inherit name build src;
- ideaItem = makeDesktopItem {
- name = "IDEA";
- exec = "idea";
- comment = "Integrated Development Environment";
- desktopName = "IntelliJ IDEA";
- genericName = "Integrated Development Environment";
+ let loName = toLower product;
+ hiName = toUpper product;
+ execName = concatStringsSep "-" (init (splitString "-" name));
+ in
+
+ with stdenv; lib.makeOverridable mkDerivation rec {
+ inherit name build src meta;
+ desktopItem = makeDesktopItem {
+ name = execName;
+ exec = execName;
+ comment = lib.replaceChars ["\n"] [" "] meta.longDescription;
+ desktopName = product;
+ genericName = meta.description;
categories = "Application;Development;";
+ icon = execName;
};
- buildInputs = [ makeWrapper patchelf p7zip ];
+ buildInputs = [ makeWrapper patchelf p7zip unzip ];
- buildCommand = ''
- tar xvzf $src
- mkdir -p $out
- cp -a idea-$build $out
+ patchPhase = ''
+ get_file_size() {
+ local fname="$1"
+ echo $(ls -l $fname | cut -d ' ' -f5)
+ }
- interpreter=$(echo ${stdenv.glibc}/lib/ld-linux*.so.2)
+ munge_size_hack() {
+ local fname="$1"
+ local size="$2"
+ strip $fname
+ truncate --size=$size $fname
+ }
- 7z x $out/idea-$build/lib/snappy-java-1.0.5.jar
- rm $out/idea-$build/lib/snappy-java-1.0.5.jar
- if [ "${stdenv.system}" == "x86_64-linux" ];then
- patchelf --set-interpreter $interpreter $out/idea-$build/bin/fsnotifier64
- patchelf --set-rpath ${stdenv.gcc.gcc}/lib64/ org/xerial/snappy/native/Linux/amd64/libsnappyjava.so
- else
- patchelf --set-interpreter $interpreter $out/idea-$build/bin/fsnotifier
- patchelf --set-rpath ${stdenv.gcc.gcc}/lib/ org/xerial/snappy/native/Linux/i386/libsnappyjava.so
- fi
- 7z a -tzip $out/idea-$build/lib/snappy-java-1.0.5.jar .
-
- mkdir -p $out/bin
-
- jdk=${jdk}/lib/openjdk
-
- makeWrapper $out/idea-$build/bin/idea.sh $out/bin/idea \
- --prefix PATH : ${jdk}/bin:${coreutils}/bin:${gnugrep}/bin:${which}/bin:${git}/bin \
- --prefix LD_RUN_PATH : ${stdenv.gcc.gcc}/lib/ \
- --prefix JDK_HOME : $jdk \
- --prefix IDEA_JDK : $jdk
-
- mkdir -p $out/share/applications
- cp "${ideaItem}/share/applications/"* $out/share/applications
- patchShebangs $out
+ interpreter=$(echo ${stdenv.glibc}/lib/ld-linux*.so.2)
+ if [ "${stdenv.system}" == "x86_64-linux" ]; then
+ target_size=$(get_file_size bin/fsnotifier64)
+ patchelf --set-interpreter "$interpreter" bin/fsnotifier64
+ munge_size_hack bin/fsnotifier64 $target_size
+ else
+ target_size=$(get_file_size bin/fsnotifier)
+ patchelf --set-interpreter "$interpreter" bin/fsnotifier
+ munge_size_hack bin/fsnotifier $target_size
+ fi
'';
- meta = {
- homepage = http://www.jetbrains.com/idea/;
- inherit description;
- inherit longDescription;
- inherit license;
- maintainers = [ stdenv.lib.maintainers.edwtjo ];
- platforms = stdenv.lib.platforms.linux;
+ installPhase = ''
+ mkdir -p $out/{bin,$name,share/pixmaps,libexec/${name}}
+ cp -a . $out/$name
+ ln -s $out/$name/bin/${loName}.png $out/share/pixmaps/${execName}.png
+ mv bin/fsnotifier* $out/libexec/${name}/.
+
+ jdk=${jdk.home}
+ item=${desktopItem}
+
+ makeWrapper "$out/$name/bin/${loName}.sh" "$out/bin/${execName}" \
+ --prefix PATH : "$out/libexec/${name},${jdk}/bin:${coreutils}/bin:${gnugrep}/bin:${which}/bin:${git}/bin" \
+ --prefix JDK_HOME : "$jdk" \
+ --prefix ${hiName}_JDK : "$jdk"
+
+ ln -s "$item/share/applications" $out/share
+ '';
+
+ };
+
+ buildAndroidStudio = { name, version, build, src, license, description }:
+ let drv = (mkIdeaProduct rec {
+ inherit name version build src;
+ product = "Studio";
+ meta = with stdenv.lib; {
+ homepage = https://developer.android.com/sdk/installing/studio.html;
+ inherit description license;
+ longDescription = ''
+ Android development environment based on IntelliJ
+ IDEA providing new features and improvements over
+ Eclipse ADT and will be the official Android IDE
+ once it's ready.
+ '';
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ edwtjo ];
+ };
+ });
+ in stdenv.lib.overrideDerivation drv (x : {
+ buildInputs = x.buildInputs ++ [ makeWrapper ];
+ installPhase = x.installPhase + ''
+ wrapProgram "$out/bin/android-studio" \
+ --set ANDROID_HOME "${androidsdk}/libexec/android-sdk-linux/"
+ '';
+ });
+
+ buildClion = { name, version, build, src, license, description }:
+ (mkIdeaProduct rec {
+ inherit name version build src;
+ product = "CLion";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/clion/";
+ inherit description license;
+ longDescription = ''
+ Enhancing productivity for every C and C++
+ developer on Linux, OS X and Windows.
+ '';
+ maintainers = with maintainers; [ edwtjo ];
+ platforms = platforms.linux;
+ };
+ });
+
+ buildIdea = { name, version, build, src, license, description }:
+ (mkIdeaProduct rec {
+ inherit name version build src;
+ product = "IDEA";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/idea/";
+ inherit description license;
+ longDescription = ''
+ IDE for Java SE, Groovy & Scala development Powerful
+ environment for building Google Android apps Integration
+ with JUnit, TestNG, popular SCMs, Ant & Maven.
+ '';
+ maintainers = with maintainers; [ edwtjo ];
+ platforms = platforms.linux;
+ };
+ });
+
+ buildRubyMine = { name, version, build, src, license, description }:
+ (mkIdeaProduct rec {
+ inherit name version build src;
+ product = "RubyMine";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/ruby/";
+ inherit description license;
+ longDescription = description;
+ maintainers = with maintainers; [ edwtjo ];
+ platforms = platforms.linux;
+ };
+ });
+
+ buildPhpStorm = { name, version, build, src, license, description }:
+ (mkIdeaProduct {
+ inherit name version build src;
+ product = "PhpStorm";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/phpstorm/";
+ inherit description license;
+ longDescription = ''
+ PhpStorm provides an editor for PHP, HTML and JavaScript
+ with on-the-fly code analysis, error prevention and
+ automated refactorings for PHP and JavaScript code.
+ '';
+ maintainers = with maintainers; [ schristo ];
+ platforms = platforms.linux;
+ };
+ });
+
+ buildWebStorm = { name, version, build, src, license, description }:
+ (mkIdeaProduct {
+ inherit name version build src;
+ product = "WebStorm";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/webstorm/";
+ inherit description license;
+ longDescription = ''
+ WebStorm provides an editor for HTML, JavaScript (incl. Node.js),
+ and CSS with on-the-fly code analysis, error prevention and
+ automated refactorings for JavaScript code.
+ '';
+ maintainers = with maintainers; [ abaldeau ];
+ platforms = platforms.linux;
+ };
+ });
+
+ buildPycharm = { name, version, build, src, license, description }:
+ (mkIdeaProduct rec {
+ inherit name version build src;
+ product = "PyCharm";
+ meta = with stdenv.lib; {
+ homepage = "https://www.jetbrains.com/pycharm/";
+ inherit description license;
+ longDescription = ''
+ Python IDE with complete set of tools for productive
+ development with Python programming language. In addition, the
+ IDE provides high-class capabilities for professional Web
+ development with Django framework and Google App Engine. It
+ has powerful coding assistance, navigation, a lot of
+ refactoring features, tight integration with various Version
+ Control Systems, Unit testing, powerful all-singing
+ all-dancing Debugger and entire customization. PyCharm is
+ developer driven IDE. It was developed with the aim of
+ providing you almost everything you need for your comfortable
+ and productive development!
+ '';
+ maintainers = with maintainers; [ jgeerds ];
+ platforms = platforms.linux;
+ };
+ }).override {
+ propagatedUserEnvPkgs = [ python ];
+ };
+
+in
+
+{
+
+ android-studio = buildAndroidStudio rec {
+ name = "android-studio-${version}";
+ version = "1.1.0";
+ build = "135.1740770";
+ description = "Android development environment based on IntelliJ IDEA";
+ license = stdenv.lib.licenses.asl20;
+ src = fetchurl {
+ url = "https://dl.google.com/dl/android/studio/ide-zips/${version}" +
+ "/android-studio-ide-${build}-linux.zip";
+ sha256 = "1r2hrld3yfaxq3mw2xmzhvrrhc7w5xlv3d18rv758hy9n40c2nr1";
};
};
-in {
+ clion = buildClion rec {
+ name = "clion-${build}";
+ version = "eap";
+ build = "141.102.4";
+ description = "C/C++ IDE. New. Intelligent. Cross-platform.";
+ license = stdenv.lib.licenses.unfree;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/cpp/${name}.tar.gz";
+ sha256 = "0qjm8wxqn171wfd7yqf5ys1g4mwl0iyhlbry29jkgkikxp7h9dym";
+ };
+ };
idea-community = buildIdea rec {
name = "idea-community-${version}";
- version = "13.1.4b";
- build = "IC-135.1230";
+ version = "14.1";
+ build = "IC-141.177.4";
description = "Integrated Development Environment (IDE) by Jetbrains, community edition";
- longDescription = ''
- Lightweight IDE for Java SE, Groovy & Scala development
- Powerful environment for building Google Android apps
- Integration with JUnit, TestNG, popular SCMs, Ant & Maven
- Free, open-source, Apache 2 licensed.
- '';
license = stdenv.lib.licenses.asl20;
src = fetchurl {
- url = "http://download-ln.jetbrains.com/idea/ideaIC-${version}.tar.gz";
- sha256 = "8b4ee25fd2934e06b87230b50e1474183ed4b331c1626a7fee69b96294d9616d";
+ url = "https://download.jetbrains.com/idea/ideaIC-${version}.tar.gz";
+ sha256 = "05irkxhmx6pisvghjalw8hcf9v3n4wn0n0zc92ahivzxlicylpr6";
};
};
idea-ultimate = buildIdea rec {
name = "idea-ultimate-${version}";
- version = "13.1.4b";
- build = "IU-135.1230";
+ version = "14.1";
+ build = "IU-141.177.4";
description = "Integrated Development Environment (IDE) by Jetbrains, requires paid license";
- longDescription = ''
- Full-featured IDE for JVM-based and polyglot development
- Java EE, Spring/Hibernate and other technologies support
- Deployment and debugging with most application servers
- Duplicate code search, dependency structure matrix, etc.
- '';
license = stdenv.lib.licenses.unfree;
src = fetchurl {
- url = "http://download-ln.jetbrains.com/idea/ideaIU-${version}.tar.gz";
- sha256 = "84660d97c9c3e4e7cfd6c2708f4685dc7322157f1e1c2888feac64df119f0606";
+ url = "https://download.jetbrains.com/idea/ideaIU-${version}.tar.gz";
+ sha256 = "10zv3m44ci7gl7163yp4wxnjy7c0g5zl34c2ibnx4c6ds6l4di2p";
+ };
+ };
+
+ ruby-mine = buildRubyMine rec {
+ name = "ruby-mine-${version}";
+ version = "7.0.4";
+ build = "139.1231";
+ description = "The Most Intelligent Ruby and Rails IDE";
+ license = stdenv.lib.licenses.unfree;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/ruby/RubyMine-${version}.tar.gz";
+ sha256 = "08b0iwccb5w9b1yk0kbs99r5mxkcyxqs9mkr57wb5j71an80yx38";
+ };
+ };
+
+ pycharm-community = buildPycharm rec {
+ name = "pycharm-community-${version}";
+ version = "4.0.5";
+ build = "139.1547";
+ description = "PyCharm 4.0 Community Edition";
+ license = stdenv.lib.licenses.asl20;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/python/${name}.tar.gz";
+ sha256 = "16na04sp9q7z10kjx8wpf9k9bv9vgv7rmd9jnrn72nhwd7bp0n1i";
+ };
+ };
+
+ pycharm-professional = buildPycharm rec {
+ name = "pycharm-professional-${version}";
+ version = "4.0.5";
+ build = "139.1547";
+ description = "PyCharm 4.0 Professional Edition";
+ license = stdenv.lib.licenses.unfree;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/python/${name}.tar.gz";
+ sha256 = "17cxznv7q47isym6l7kbp3jdzdgj02jayygy42x4bwjmg579v1gg";
+ };
+ };
+
+ phpstorm = buildPhpStorm rec {
+ name = "phpstorm-${version}";
+ version = "8.0.3";
+ build = "PS-139.1348";
+ description = "Professional IDE for Web and PHP developers";
+ license = stdenv.lib.licenses.unfree;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/webide/PhpStorm-${version}.tar.gz";
+ sha256 = "1x67nfr3nap93cx7yhdrp02xvp1v6g74zy7hdmhx41sal7hzy49b";
+ };
+ };
+
+ webstorm = buildWebStorm rec {
+ name = "webstorm-${version}";
+ version = "9.0.3";
+ build = "139.1112";
+ description = "Professional IDE for Web and JavaScript devlopment";
+ license = stdenv.lib.licenses.unfree;
+ src = fetchurl {
+ url = "https://download.jetbrains.com/webstorm/WebStorm-${version}.tar.gz";
+ sha256 = "e4cfe7b5f1220b68d880c4f236df9c9df2b1efcc04775afad6149d949f45f0aa";
};
};
diff --git a/pkgs/applications/editors/idea/pycharm.nix b/pkgs/applications/editors/idea/pycharm.nix
deleted file mode 100644
index 6a2064549bb..00000000000
--- a/pkgs/applications/editors/idea/pycharm.nix
+++ /dev/null
@@ -1,115 +0,0 @@
-{ stdenv, fetchurl, makeDesktopItem, makeWrapper, patchelf, p7zip, jdk
-, coreutils, gnugrep, which, git, python
-}:
-
-let
-
- buildPycharm =
- { name, version, build, src, description, license }:
-
- stdenv.mkDerivation rec {
- inherit name build src;
- desktopItem = makeDesktopItem {
- name = "pycharm";
- exec = "pycharm";
- comment = "Powerful Python and Django IDE";
- desktopName = "PyCharm";
- genericName = "Powerful Python and Django IDE";
- categories = "Application;Development;";
- icon = "pycharm";
- };
-
- buildInputs = [ makeWrapper patchelf p7zip ];
-
- propagatedUserEnvPkgs = [ python ];
-
- patchPhase = ''
- interpreter="$(echo ${stdenv.glibc}/lib/ld-linux*.so.2)"
- snappyPath="lib/snappy-java-1.0.5"
-
- 7z x -o"$snappyPath" "$snappyPath.jar"
- if [ "${stdenv.system}" == "x86_64-linux" ]; then
- patchelf --set-interpreter "$interpreter" bin/fsnotifier64
- patchelf --set-rpath ${stdenv.gcc.gcc}/lib64/ "$snappyPath/org/xerial/snappy/native/Linux/amd64/libsnappyjava.so"
- else
- patchelf --set-interpreter "$interpreter" bin/fsnotifier
- patchelf --set-rpath ${stdenv.gcc.gcc}/lib/ "$snappyPath/org/xerial/snappy/native/Linux/i386/libsnappyjava.so"
- fi
- 7z a -tzip "$snappyPath.jar" ./"$snappyPath"/*
- rm -vr "$snappyPath"
- '';
-
- installPhase = ''
- mkdir -vp "$out/bin" "$out/$name" "$out/share/pixmaps"
- cp -va . "$out/$name"
- ln -s "$out/$name/bin/pycharm.png" "$out/share/pixmaps/"
-
- jdk="${jdk}/lib/openjdk"
- makeWrapper "$out/$name/bin/pycharm.sh" "$out/bin/pycharm" \
- --prefix PATH : "${jdk}/bin:${coreutils}/bin:${gnugrep}/bin:${which}/bin:${git}/bin" \
- --prefix LD_RUN_PATH : "${stdenv.gcc.gcc}/lib/" \
- --prefix JDK_HOME : "$jdk" \
- --prefix PYCHARM_JDK : "$jdk"
-
- cp -a "${desktopItem}"/* "$out"
- '';
-
- meta = with stdenv.lib; {
- homepage = "https://www.jetbrains.com/pycharm/";
- inherit description;
- inherit license;
- maintainers = [ maintainers.jgeerds ];
- platforms = platforms.linux;
- };
- };
-
-in {
-
- pycharm-community-313 = buildPycharm rec {
- name = "pycharm-community-${version}";
- version = "3.1.3";
- build = "133.1347";
- description = "PyCharm 3.1 Community Edition";
- license = stdenv.lib.licenses.asl20;
- src = fetchurl {
- url = "http://download.jetbrains.com/python/${name}.tar.gz";
- sha256 = "f671ee4c99207c179f168b5b98fa23afe90a94c3a3914367b95a46b0c2881b23";
- };
- };
-
- pycharm-community-341 = buildPycharm rec {
- name = "pycharm-community-${version}";
- version = "3.4.1";
- build = "135.1057";
- description = "PyCharm 3.4 Community Edition";
- license = stdenv.lib.licenses.asl20;
- src = fetchurl {
- url = "http://download.jetbrains.com/python/${name}.tar.gz";
- sha256 = "96427b1e842e7c09141ec4d3ede627c5ca7d821c0d6c98169b56a34f9035ef64";
- };
- };
-
- pycharm-professional-313 = buildPycharm rec {
- name = "pycharm-professional-${version}";
- version = "3.1.3";
- build = "133.1347";
- description = "PyCharm 3.1 Professional Edition";
- license = stdenv.lib.licenses.unfree;
- src = fetchurl {
- url = "http://download.jetbrains.com/python/${name}.tar.gz";
- sha256 = "e0c2db8f18cb825a95de6ddc4b0b9f93c5643bf34cca9f1b3c2fa37fd7c14f11";
- };
- };
-
- pycharm-professional-341 = buildPycharm rec {
- name = "pycharm-professional-${version}";
- version = "3.4.1";
- build = "135.1057";
- description = "PyCharm 3.4 Professional Edition";
- license = stdenv.lib.licenses.unfree;
- src = fetchurl {
- url = "http://download.jetbrains.com/python/${name}.tar.gz";
- sha256 = "e4f85f3248e8985ac9f8c326543f979b47ba1d7ac6b128a2cf2b3eb8ec545d2b";
- };
- };
-}
diff --git a/pkgs/applications/editors/jedit/build.xml.patch b/pkgs/applications/editors/jedit/build.xml.patch
new file mode 100644
index 00000000000..2f630f18ab7
--- /dev/null
+++ b/pkgs/applications/editors/jedit/build.xml.patch
@@ -0,0 +1,257 @@
+--- a/build.xml 2015-02-04 08:47:37.000000000 +0100
++++ b/build.xml 2015-02-17 14:06:42.455283148 +0100
+@@ -43,16 +43,6 @@
+
+
+-
+-
+-
+-
+-
+-
+
+
+@@ -90,51 +80,8 @@
+ value="true"/>
+
+
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+
++ depends="init">
+
+
+@@ -239,37 +186,6 @@
+
+
+
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+
+
+
+
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+
+
+
+
+
+-
+
+
+
+
+
+@@ -622,7 +512,7 @@
+
+
+
++ depends="init">
+
+
+@@ -668,7 +558,7 @@
+
+
+
++ depends="init,setup,unpack-docbook-xsl">
+
+
+
+@@ -692,7 +582,7 @@
+
+
+
++ depends="init,setup,unpack-docbook-xsl">
+
+
+
+@@ -716,7 +606,7 @@
+
+
+
++ depends="init,setup,unpack-docbook-xsl">
+
+
+
+@@ -851,7 +741,7 @@
+
+
+
++ depends="init,setup,unpack-docbook-xsl">
+
+
+@@ -1154,7 +1044,7 @@
+
+
+
++ depends="init">
+
+
+
+
+
+
+@@ -1295,7 +1185,7 @@
+
+
+
+
+
+
+
++ depends="init,setup">
+
+
+@@ -1592,7 +1482,7 @@
+
+
+
+
+
+
+
+
+
diff --git a/pkgs/applications/editors/jedit/default.nix b/pkgs/applications/editors/jedit/default.nix
index 8a57f650fb4..7dfb651d7d3 100644
--- a/pkgs/applications/editors/jedit/default.nix
+++ b/pkgs/applications/editors/jedit/default.nix
@@ -1,32 +1,47 @@
-{ stdenv, fetchurl, ant, jdk }:
+{ stdenv, fetchurl, ant, jdk, commonsBsf, commonsLogging }:
-let version = "4.4.2"; in
+let
+ version = "5.2.0";
+ bsh = fetchurl {
+ url = http://www.beanshell.org/bsh-2.0b4.jar;
+ sha256 = "1di7hj2yms1m3wa8k70jpw0wzfnrgibpqnvdk33ahfaqi03mqfci";
+ };
+ bcpg = fetchurl {
+ url = http://central.maven.org/maven2/org/bouncycastle/bcpg-jdk16/1.46/bcpg-jdk16-1.46.jar;
+ sha256 = "16xhmwks4l65m5x150nd23y5lyppha9sa5fj65rzhxw66gbli82d";
+ };
+ jsr305 = fetchurl {
+ url = http://central.maven.org/maven2/com/google/code/findbugs/jsr305/2.0.0/jsr305-2.0.0.jar;
+ sha256 = "0s74pv8qjc42c7q8nbc0c3b1hgx0bmk3b8vbk1z80p4bbgx56zqy";
+ };
+in
stdenv.mkDerivation {
name = "jedit-${version}";
-
src = fetchurl {
url = "mirror://sourceforge/jedit/jedit${version}source.tar.bz2";
- sha256 = "5e9ad9c32871b77ef0b9fe46dcfcea57ec52558d36113b7280194a33430b8ceb";
+ sha256 = "03wmbh90rl5lsc35d7jwcp9j5qyyzq1nccxf4fal8bmnx8n4si0x";
};
- buildInputs = [ ant jdk ];
+ buildInputs = [ ant jdk commonsBsf commonsLogging ];
- sourceRoot = "jEdit";
+ # This patch removes from the build process:
+ # - the automatic download of dependencies (see configurePhase);
+ # - the tests
+ patches = [ ./build.xml.patch ];
+
+ configurePhase = ''
+ mkdir -p lib/ant-contrib/ lib/scripting lib/compile lib/default-plugins
+ cp ${ant}/lib/ant/lib/ant-contrib-*.jar lib/ant-contrib/
+ cp ${bsh} ${bcpg} lib/scripting/
+ cp ${jsr305} lib/compile/
+ '';
buildPhase = "ant build";
installPhase = ''
mkdir -p $out/share/jEdit
- cp build/jedit.jar $out/share/jEdit
- mkdir -p $out/share/jEdit/modes
- cp -r modes/* $out/share/jEdit/modes
- mkdir -p $out/share/jEdit/icons
- cp -r icons/* $out/share/jEdit/icons
- mkdir -p $out/share/jEdit/macros
- cp -r macros/* $out/share/jEdit/macros
- mkdir -p $out/share/jEdit/doc
- cp -r doc/* $out/share/jEdit/doc
+ cp -r build/jedit.jar doc icons keymaps macros modes startup $out/share/jEdit
sed -i "s|Icon=.*|Icon=$out/share/jEdit/icons/jedit-icon48.png|g" package-files/linux/deb/jedit.desktop
mkdir -p $out/share/applications
@@ -35,7 +50,7 @@ stdenv.mkDerivation {
patch package-files/linux/jedit << EOF
5a6,8
> # specify the correct JAVA_HOME
- > JAVA_HOME=${jdk.jre}/lib/openjdk/jre
+ > JAVA_HOME=${jdk.jre.home}/jre
>
EOF
sed -i "s|/usr/share/jEdit/@jar.filename@|$out/share/jEdit/jedit.jar|g" package-files/linux/jedit
@@ -44,9 +59,11 @@ stdenv.mkDerivation {
chmod +x $out/bin/jedit
'';
- meta = {
+ meta = with stdenv.lib; {
description = "Mature programmer's text editor (Java based)";
homepage = http://www.jedit.org;
- license = "GPL";
+ license = licenses.gpl2;
+ platforms = platforms.unix;
+ maintainers = [ maintainers.vbgl ];
};
}
diff --git a/pkgs/applications/editors/kdevelop/default.nix b/pkgs/applications/editors/kdevelop/default.nix
index b815b052347..b0ac24ee61a 100644
--- a/pkgs/applications/editors/kdevelop/default.nix
+++ b/pkgs/applications/editors/kdevelop/default.nix
@@ -1,20 +1,22 @@
{ stdenv, fetchurl, kdevplatform, cmake, pkgconfig, automoc4, shared_mime_info,
- kdebase_workspace, gettext, perl, okteta, qjson }:
+ kdebase_workspace, gettext, perl, okteta, qjson, kate, konsole, kde_runtime, oxygen_icons }:
stdenv.mkDerivation rec {
name = "${pname}-${version}";
- version = "4.6.0";
+ version = "4.7.1";
pname = "kdevelop";
src = fetchurl {
url = "mirror://kde/stable/${pname}/${version}/src/${name}.tar.xz";
- sha256 = "1ee9e7b8c46f575dd29d920cfd6284130f2e738a2e1f52dfd97b075fab2e4c73";
+ sha256 = "e3ad5377f53739a67216d37cda3f88c03f8fbb0c96e2a9ef4056df3c124e95c1";
};
buildInputs = [ kdevplatform kdebase_workspace okteta qjson ];
nativeBuildInputs = [ cmake pkgconfig automoc4 shared_mime_info gettext perl ];
+ propagatedUserEnvPkgs = [ kdevplatform kate konsole kde_runtime oxygen_icons ];
+
NIX_CFLAGS_COMPILE = "-I${okteta}/include/KDE";
meta = with stdenv.lib; {
diff --git a/pkgs/applications/editors/leafpad/default.nix b/pkgs/applications/editors/leafpad/default.nix
new file mode 100644
index 00000000000..fc35a993bad
--- /dev/null
+++ b/pkgs/applications/editors/leafpad/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchurl, intltool, pkgconfig, gtk }:
+
+stdenv.mkDerivation rec {
+ version = "0.8.18.1";
+ name = "leafpad-${version}";
+ src = fetchurl {
+ url = "http://download.savannah.gnu.org/releases/leafpad/${name}.tar.gz";
+ sha256 = "0b0az2wvqgvam7w0ns1j8xp2llslm1rx6h7zcsy06a7j0yp257cm";
+ };
+
+ buildInputs = [ intltool pkgconfig gtk ];
+
+ configureFlags = [
+ "--enable-chooser"
+ ];
+
+ meta = with stdenv.lib; {
+ description = "A notepad clone for GTK+ 2.0";
+ homepage = http://tarot.freeshell.org/leafpad;
+ platforms = platforms.linux;
+ maintainers = [ maintainers.flosse ];
+ license = licenses.gpl3;
+ };
+}
diff --git a/pkgs/applications/editors/lighttable/default.nix b/pkgs/applications/editors/lighttable/default.nix
index b5ab1950e2b..d4fa56898c3 100644
--- a/pkgs/applications/editors/lighttable/default.nix
+++ b/pkgs/applications/editors/lighttable/default.nix
@@ -5,7 +5,7 @@
let
libPath = stdenv.lib.makeLibraryPath [
- stdenv.gcc.gcc zlib glib dbus gtk atk pango freetype libgnome_keyring3 nss
+ stdenv.cc.cc zlib glib dbus gtk atk pango freetype libgnome_keyring3 nss
fontconfig gdk_pixbuf cairo cups expat libgpgerror alsaLib nspr gnome3.gconf
xlibs.libXrender xlibs.libX11 xlibs.libXext xlibs.libXdamage xlibs.libXtst
xlibs.libXcomposite xlibs.libXi xlibs.libXfixes
@@ -14,21 +14,21 @@ in
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
stdenv.mkDerivation rec {
- name = "LightTable-${version}";
- version = "0.6.7";
+ name = "lighttable-${version}";
+ version = "0.7.2";
src =
if stdenv.system == "i686-linux" then
fetchurl {
name = "LightTableLinux.tar.gz";
- url = https://d35ac8ww5dfjyg.cloudfront.net/playground/bins/0.6.7/LightTableLinux.tar.gz;
- sha256 = "3b09f9665ed1b4abb7c1ca16286ac7222caf6dc124059be6db4cb9f5fd041e73";
+ url = "https://d35ac8ww5dfjyg.cloudfront.net/playground/bins/${version}/LightTableLinux.tar.gz";
+ sha256 = "1q5m50r319xn9drfv3cyfja87b7dfhni9d9gmz9733idq3l5fl9i";
}
else
fetchurl {
name = "LightTableLinux64.tar.gz";
- url = https://d35ac8ww5dfjyg.cloudfront.net/playground/bins/0.6.7/LightTableLinux64.tar.gz;
- sha256 = "710d670ccc30aadba521ccb723388679ee6404aac662297a005432c811d59e82";
+ url = "https://d35ac8ww5dfjyg.cloudfront.net/playground/bins/${version}/LightTableLinux64.tar.gz";
+ sha256 = "1jnn103v5qrplkb5ik9p8whfqclcq2r1qv666hp3jaiwb46vhf3c";
};
buildInputs = [ makeWrapper ];
@@ -40,11 +40,11 @@ stdenv.mkDerivation rec {
mv LightTable $out/
patchelf \
- --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
- --set-rpath ${libPath}:${stdenv.gcc.gcc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
+ --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+ --set-rpath ${libPath}:${stdenv.cc.cc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
$out/LightTable/ltbin
- ln -s ${udev}/lib/libudev.so.1 $out/LightTable/libudev.so.0
+ ln -sf ${udev}/lib/libudev.so.1 $out/LightTable/libudev.so.0
makeWrapper $out/LightTable/ltbin $out/bin/lighttable \
--prefix "LD_LIBRARY_PATH" : $out/LightTable
diff --git a/pkgs/applications/editors/mg/default.nix b/pkgs/applications/editors/mg/default.nix
index 6901aed774b..45a527c7484 100644
--- a/pkgs/applications/editors/mg/default.nix
+++ b/pkgs/applications/editors/mg/default.nix
@@ -24,7 +24,7 @@ stdenv.mkDerivation rec {
meta = {
homepage = http://homepage.boetes.org/software/mg/;
description = "Micro GNU/emacs, a portable version of the mg maintained by the OpenBSD team";
- license = "public domain";
+ license = stdenv.lib.licenses.publicDomain;
platforms = stdenv.lib.platforms.all;
};
}
diff --git a/pkgs/applications/editors/monodevelop/builder.sh b/pkgs/applications/editors/monodevelop/builder.sh
deleted file mode 100644
index c069edb3a6d..00000000000
--- a/pkgs/applications/editors/monodevelop/builder.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-source $stdenv/setup
-source $makeWrapper
-
-export MONO_GAC_PREFIX=$monodoc:$gtksharp
-
-postInstall() {
- mv $out/bin $out/bin-orig
- mkdir $out/bin
-
- moz=$(ls $mozilla/lib/*/libgtkembedmoz.so)
-
- for i in $out/bin-orig/*; do
- echo "wrapping $(basename $i)"
- # !!! TODO: figure out the MONO_GAC_PREFIX automatically
- makeWrapper "$i" "$out/bin/$(basename $i)" \
- --suffix PATH ':' "$(dirname $(type -p mono))" \
- --suffix PATH ':' "$(dirname $(type -p mono))" \
- --suffix LD_LIBRARY_PATH ':' "$gtksharp/lib" \
- --suffix MONO_GAC_PREFIX ':' "$gtksharp" \
- --suffix MONO_GAC_PREFIX ':' "$gtkmozembedsharp" \
- --suffix MONO_GAC_PREFIX ':' "$gtksourceviewsharp" \
- --suffix MONO_GAC_PREFIX ':' "$monodoc" \
- --set MOZILLA_FIVE_HOME "$(dirname $moz)"
- done
-}
-
-genericBuild
-
diff --git a/pkgs/applications/editors/monodevelop/default.nix b/pkgs/applications/editors/monodevelop/default.nix
index aad6325fa44..4e8e6079ff1 100644
--- a/pkgs/applications/editors/monodevelop/default.nix
+++ b/pkgs/applications/editors/monodevelop/default.nix
@@ -1,26 +1,83 @@
-{ stdenv, fetchurl, file, mono, gtksharp, gtksourceviewsharp
-, gtkmozembedsharp, monodoc
-, perl, perlXMLParser, pkgconfig
-, glib, gtk, GConf, gnome_vfs, libbonobo, libglade, libgnome
-, mozilla, makeWrapper
+{ stdenv, fetchurl, fetchgit
+, autoconf, automake, pkgconfig, shared_mime_info, intltool
+, glib, mono, gtk-sharp, gnome, gnome-sharp, unzip
}:
-stdenv.mkDerivation {
- name = "monodevelop-0.6-pre2315";
- builder = ./builder.sh;
+stdenv.mkDerivation rec {
+ version = "5.7.0.660";
+ revision = "6a74f9bdb90d9415b597064d815c9be38b401fee";
+ name = "monodevelop-${version}";
- src = fetchurl {
- url = http://tarballs.nixos.org/monodevelop-0.6-pre2315.tar.bz2;
- md5 = "8c33df5629b0676b7ab552854c1de6fd";
- };
-
- patches = [./prefix.patch];
-
- buildInputs = [
- file mono gtksharp gtksourceviewsharp perl perlXMLParser pkgconfig
- glib gtk GConf gnome_vfs libbonobo libglade libgnome
- gtkmozembedsharp monodoc
+ srcs = [
+ (fetchurl {
+ url = "http://download.mono-project.com/sources/monodevelop/${name}.tar.bz2";
+ sha256 = "0i9fpjkcys991dhxh02zf9imar3aj6fldk9ymy09vmr10f4d7vbf";
+ })
+ (fetchurl {
+ url = "https://launchpadlibrarian.net/153448659/NUnit-2.6.3.zip";
+ sha256 = "0vzbziq44zy7fyyhb44mf9ypfi7gvs17rxpg8c9d9lvvdpkshhcp";
+ })
+ (fetchurl {
+ url = "https://launchpadlibrarian.net/68057829/NUnit-2.5.10.11092.zip";
+ sha256 = "0k5h5bz1p2v3d0w0hpkpbpvdkcszgp8sr9ik498r1bs72w5qlwnc";
+ })
+ (fetchgit {
+ url = "https://github.com/mono/nuget-binary.git";
+ rev = "ecb27dd49384d70b6c861d28763906f2b25b7c8";
+ sha256 = "0dj0yglgwn07xw2crr66vl0vcgnr6m041pynyq0kdd0z8nlp92ki";
+ })
];
-
- inherit mozilla monodoc gtksharp gtkmozembedsharp gtksourceviewsharp makeWrapper;
+
+ sourceRoot = "monodevelop-5.7";
+
+ postPatch = ''
+ # From https://bugzilla.xamarin.com/show_bug.cgi?id=23696#c19
+
+ # it seems parts of MonoDevelop 5.2+ need NUnit 2.6.4, which isn't included
+ # (?), so download it and put it in the right place in the tree
+ mkdir -v -p packages/NUnit.2.6.3/lib
+ cp -vfR ../NUnit-2.6.3/bin/framework/* packages/NUnit.2.6.3/lib
+ mkdir -v -p packages/NUnit.Runners.2.6.3/tools/lib
+ cp -vfR ../NUnit-2.6.3/bin/lib/* packages/NUnit.Runners.2.6.3/tools/lib
+
+ # cecil needs NUnit 2.5.10 - this is also missing from the tar
+ cp -vfR ../NUnit-2.5.10.11092/bin/net-2.0/framework/* external/cecil/Test/libs/nunit-2.5.10
+
+ # the tar doesn't include the nuget binary, so grab it from github and copy it
+ # into the right place
+ cp -vfR ../nuget-binary-*/* external/nuget-binary/
+ '';
+
+ buildInputs = [
+ autoconf automake pkgconfig shared_mime_info intltool
+ mono gtk-sharp gnome-sharp unzip
+ ];
+
+ preConfigure = "patchShebangs ./configure";
+ preBuild = ''
+ cat > ./buildinfo < export MONO_GAC_PREFIX=${gnome-sharp}:${gtk-sharp}:\$MONO_GAC_PREFIX
+ > export PATH=${mono}/bin:\$PATH
+ > export LD_LIBRARY_PATH=${glib}/lib:${gnome.libgnomeui}/lib:${gnome.gnome_vfs}/lib:${gnome-sharp}/lib:${gtk-sharp}/lib:${gtk-sharp.gtk}/lib:\$LD_LIBRARY_PATH
+ >
+ EOF
+ done
+ '';
+
+ dontStrip = true;
+
+ meta = with stdenv.lib; {
+ platforms = platforms.linux;
+ maintainers = with maintainers; [ obadz ];
+ };
}
diff --git a/pkgs/applications/editors/monodevelop/prefix.patch b/pkgs/applications/editors/monodevelop/prefix.patch
deleted file mode 100644
index 5ab0b4042dd..00000000000
--- a/pkgs/applications/editors/monodevelop/prefix.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-diff -rc MonoDevelop-orig/Makefile.in MonoDevelop/Makefile.in
-*** MonoDevelop-orig/Makefile.in 2005-03-09 17:43:58.000000000 +0100
---- MonoDevelop/Makefile.in 2005-03-09 18:10:20.000000000 +0100
-***************
-*** 298,304 ****
- # (mkdir ../../build/bin/ hack)
- SUBDIRS = Core build po Extras
- bin_SCRIPTS = monodevelop
-! gnome_data = @gnome_prefix@/share
- desktopdir = $(gnome_data)/applications
- desktop_DATA = monodevelop.desktop
- pixmapdir = $(gnome_data)/pixmaps
---- 298,304 ----
- # (mkdir ../../build/bin/ hack)
- SUBDIRS = Core build po Extras
- bin_SCRIPTS = monodevelop
-! gnome_data = @prefix@/share
- desktopdir = $(gnome_data)/applications
- desktop_DATA = monodevelop.desktop
- pixmapdir = $(gnome_data)/pixmaps
-***************
-*** 809,818 ****
- all:
-
- install-data-hook:
-! $(UPDATE_MIME_DB) $(gnome_data)/mime
-
- uninstall-hook:
-! $(UPDATE_MIME_DB) $(gnome_data)/mime
-
- run: runmd
-
---- 809,818 ----
- all:
-
- install-data-hook:
-! # $(UPDATE_MIME_DB) $(gnome_data)/mime
-
- uninstall-hook:
-! # $(UPDATE_MIME_DB) $(gnome_data)/mime
-
- run: runmd
-
-Only in MonoDevelop: Makefile.in~
diff --git a/pkgs/applications/editors/monodoc/builder.sh b/pkgs/applications/editors/monodoc/builder.sh
deleted file mode 100644
index bcea7a7a89a..00000000000
--- a/pkgs/applications/editors/monodoc/builder.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-source $stdenv/setup
-source $makeWrapper
-
-postInstall() {
- mv $out/bin $out/bin-orig
- mkdir $out/bin
-
- for i in $out/bin-orig/*; do
- echo "wrapping $(basename $i)"
- # !!! TODO: figure out the MONO_GAC_PREFIX automatically
- makeWrapper "$i" "$out/bin/$(basename $i)" \
- --suffix PATH ':' "$(dirname $(type -p mono))" \
- --suffix MONO_GAC_PREFIX ':' "$gtksharp" \
- --suffix MONO_GAC_PREFIX ':' "$out"
- done
-}
-
-genericBuild
-
-
diff --git a/pkgs/applications/editors/monodoc/default.nix b/pkgs/applications/editors/monodoc/default.nix
deleted file mode 100644
index 0e8421646a8..00000000000
--- a/pkgs/applications/editors/monodoc/default.nix
+++ /dev/null
@@ -1,15 +0,0 @@
-{stdenv, fetchurl, mono, gtksharp, pkgconfig, makeWrapper}:
-
-stdenv.mkDerivation {
- name = "monodoc-1.0.6";
-
- builder = ./builder.sh;
- src = fetchurl {
- url = http://tarballs.nixos.org/monodoc-1.0.6.tar.gz;
- md5 = "f2fc27e8e4717d90dc7efa2450625693";
- };
-
- buildInputs = [mono gtksharp pkgconfig];
-
- inherit gtksharp makeWrapper;
-}
diff --git a/pkgs/applications/editors/music/tuxguitar/default.nix b/pkgs/applications/editors/music/tuxguitar/default.nix
new file mode 100644
index 00000000000..768842a3875
--- /dev/null
+++ b/pkgs/applications/editors/music/tuxguitar/default.nix
@@ -0,0 +1,44 @@
+{ stdenv, fetchurl, swt, jdk, makeWrapper, alsaLib }:
+
+let metadata = assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
+ if stdenv.system == "i686-linux" then
+ { arch = "x86"; sha256 = "1qmb51k0538pn7gv4nsvhfv33xik4l4af0qmpllkzrikmj8wvzlb"; }
+ else
+ { arch = "x86_64"; sha256 = "12af47jhlrh9aq5b3d13l7cdhlndgnfpy61gz002hajbq7i00ixh"; };
+in stdenv.mkDerivation rec {
+ version = "1.2";
+ name = "tuxguitar-${version}";
+
+ src = fetchurl {
+ url = "mirror://sourceforge/tuxguitar/${name}-linux-${metadata.arch}.tar.gz";
+ sha256 = metadata.sha256;
+ };
+
+ buildInputs = [ makeWrapper ];
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp -r lib share $out/
+ cp tuxguitar $out/bin/tuxguitar
+ cp tuxguitar.jar $out/lib
+
+ ln -s $out/share $out/bin/share
+
+ wrapProgram $out/bin/tuxguitar \
+ --set JAVA "${jdk}/bin/java" \
+ --prefix LD_LIBRARY_PATH : "$out/lib/:${swt}/lib:${alsaLib}/lib" \
+ --prefix CLASSPATH : "${swt}/jars/swt.jar:$out/lib/tuxguitar.jar:$out/lib/itext.jar"
+ '';
+
+ meta = with stdenv.lib; {
+ description = "A multitrack guitar tablature editor";
+ longDescription = ''
+ TuxGuitar is a multitrack guitar tablature editor and player written
+ in Java-SWT. It can open GuitarPro, PowerTab and TablEdit files.
+ '';
+ homepage = http://www.tuxguitar.com.ar/;
+ license = licenses.lgpl2;
+ maintainers = [ maintainers.ardumont ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/editors/nano/default.nix b/pkgs/applications/editors/nano/default.nix
index caea8758d95..e7b96bd4b7d 100644
--- a/pkgs/applications/editors/nano/default.nix
+++ b/pkgs/applications/editors/nano/default.nix
@@ -1,22 +1,37 @@
-{ stdenv, fetchurl, ncurses, gettext }:
+{ stdenv, fetchurl
+, ncurses
+, gettext ? null
+, enableNls ? true
+, enableTiny ? false
+}:
-stdenv.mkDerivation (rec {
- pname = "nano";
- version = "2.3.6";
+assert enableNls -> (gettext != null);
- name = "${pname}-${version}";
+with stdenv.lib;
+stdenv.mkDerivation rec {
+ name = "nano-${version}";
+ version = "2.4.0";
src = fetchurl {
url = "mirror://gnu/nano/${name}.tar.gz";
- sha256 = "a74bf3f18b12c1c777ae737c0e463152439e381aba8720b4bc67449f36a09534";
+ sha256 = "1gbm9bcv4k55y01r5q8a8a9s3yrrgq3z5jxxiij3wl404r8gnxjh";
};
+ buildInputs = [ ncurses ] ++ optional enableNls gettext;
+ configureFlags = ''
+ --sysconfdir=/etc
+ ${optionalString (!enableNls) "--disable-nls"}
+ ${optionalString enableTiny "--enable-tiny"}
+ '';
- buildInputs = [ ncurses gettext ];
-
- configureFlags = "sysconfdir=/etc";
+ postPatch = stdenv.lib.optionalString stdenv.isDarwin ''
+ substituteInPlace src/text.c --replace "__time_t" "time_t"
+ '';
meta = {
homepage = http://www.nano-editor.org/;
description = "A small, user-friendly console text editor";
+ license = licenses.gpl3Plus;
+ maintainers = with maintainers; [ joachifm ];
+ platforms = platforms.all;
};
-})
+}
diff --git a/pkgs/applications/editors/nedit/builder.sh b/pkgs/applications/editors/nedit/builder.sh
deleted file mode 100644
index 15706b0c37d..00000000000
--- a/pkgs/applications/editors/nedit/builder.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-source $stdenv/setup
-
-export NIX_CFLAGS_COMPILE="-DBUILD_UNTESTED_NEDIT -L$motif/lib $NIX_CFLAGS_COMPILE"
-
-installPhase() {
- mkdir -p $out/bin
- cp -p source/nedit source/nc $out/bin
-}
-
-genericBuild
diff --git a/pkgs/applications/editors/nedit/default.nix b/pkgs/applications/editors/nedit/default.nix
index bd53f8d81d0..a4dfc4719dc 100644
--- a/pkgs/applications/editors/nedit/default.nix
+++ b/pkgs/applications/editors/nedit/default.nix
@@ -1,22 +1,26 @@
-{stdenv, fetchurl, x11, motif, libXpm}:
+{ stdenv, fetchurl, x11, motif, libXpm }:
assert stdenv.isLinux;
-stdenv.mkDerivation {
- name = "nedit-5.5";
- builder = ./builder.sh;
+stdenv.mkDerivation rec {
+ name = "nedit-5.6";
src = fetchurl {
- url = http://nl.nedit.org/ftp/v5_5/nedit-5.5-src.tar.bz2;
- md5 = "48cb3dce52d44988f3a4d7c6f47b6bbe";
+ url = "mirror://sourceforge/nedit/nedit-source/${name}-src.tar.gz";
+ sha256 = "023hwpqc57mnzvg6p7jda6193afgjzxzajlhwhqvk3jq2kdv6zna";
};
- patches = [./dynamic.patch];
- inherit motif;
- buildInputs = [x11 motif libXpm];
+ buildInputs = [ x11 motif libXpm ];
buildFlags = if stdenv.isLinux then "linux" else "";
+ NIX_CFLAGS_COMPILE="-DBUILD_UNTESTED_NEDIT -L${motif}/lib";
+
+ installPhase = ''
+ mkdir -p $out/bin
+ cp -p source/nedit source/nc $out/bin
+ '';
+
meta = {
homepage = http://www.nedit.org;
};
diff --git a/pkgs/applications/editors/nedit/dynamic.patch b/pkgs/applications/editors/nedit/dynamic.patch
deleted file mode 100644
index adb2cbc2592..00000000000
--- a/pkgs/applications/editors/nedit/dynamic.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-diff -rc nedit-5.5-orig/makefiles/Makefile.linux nedit-5.5/makefiles/Makefile.linux
-*** nedit-5.5-orig/makefiles/Makefile.linux 2003-05-20 02:27:56.000000000 +0200
---- nedit-5.5/makefiles/Makefile.linux 2005-12-03 00:42:23.000000000 +0100
-***************
-*** 17,27 ****
- # To test if the Motif library exports the runtime version
- # add -DHAVE__XMVERSIONSTRING to CFLAGS
- #
-! CFLAGS=-O -I/usr/X11R6/include -DUSE_DIRENT -DUSE_LPR_PRINT_CMD
-
- ARFLAGS=-urs
-
-! LIBS= -L/usr/X11R6/lib -Wl,-Bstatic -lXm -Wl,-Bdynamic -lXp -lXpm -lXext -lXt -lSM -lICE -lX11 -lm
-
- include Makefile.common
-
---- 17,27 ----
- # To test if the Motif library exports the runtime version
- # add -DHAVE__XMVERSIONSTRING to CFLAGS
- #
-! CFLAGS=-O -DUSE_DIRENT -DUSE_LPR_PRINT_CMD
-
- ARFLAGS=-urs
-
-! LIBS= -lXm -lXp -lXpm -lXext -lXt -lSM -lICE -lX11 -lm
-
- include Makefile.common
diff --git a/pkgs/applications/editors/neovim/default.nix b/pkgs/applications/editors/neovim/default.nix
new file mode 100644
index 00000000000..1c1c050b000
--- /dev/null
+++ b/pkgs/applications/editors/neovim/default.nix
@@ -0,0 +1,65 @@
+{ stdenv, fetchgit, fetchurl, unzip, callPackage, ncurses, gettext, pkgconfig,
+cmake, pkgs, lpeg, lua, luajit, luaMessagePack, luabitop }:
+
+stdenv.mkDerivation rec {
+ name = "neovim-nightly";
+
+ version = "nightly";
+
+ src = fetchgit {
+ url = "https://github.com/neovim/neovim";
+ rev = "68fcd8b696dae33897303c9f8265629a31afbf17";
+ sha256 = "0hxkcy641jpn4qka44gfvhmb6q3dkjx6lvn9748lcl2gx2d36w4i";
+ };
+
+ libmsgpack = stdenv.mkDerivation rec {
+ version = "0.5.9";
+ name = "libmsgpack-${version}";
+
+ src = fetchgit {
+ rev = "ecf4b09acd29746829b6a02939db91dfdec635b4";
+ url = "https://github.com/msgpack/msgpack-c";
+ sha256 = "076ygqgxrc3vk2l20l8x2cgcv05py3am6mjjkknr418pf8yav2ww";
+ };
+
+ buildInputs = [ cmake ];
+
+ meta = with stdenv.lib; {
+ description = "MessagePack implementation for C and C++";
+ homepage = http://msgpack.org;
+ maintainers = [ maintainers.manveru ];
+ license = licenses.asl20;
+ platforms = platforms.all;
+ };
+ };
+
+ enableParallelBuilding = true;
+
+ buildInputs = [
+ ncurses
+ pkgconfig
+ cmake
+ pkgs.libuvVersions.v0_11_29
+ luajit
+ lua
+ lpeg
+ luaMessagePack
+ luabitop
+ libmsgpack
+ ];
+ nativeBuildInputs = [ gettext ];
+
+ LUA_CPATH="${lpeg}/lib/lua/${lua.luaversion}/?.so;${luabitop}/lib/lua/5.2/?.so";
+ LUA_PATH="${luaMessagePack}/share/lua/5.1/?.lua";
+ cmakeFlags = [
+ "-DUSE_BUNDLED_MSGPACK=ON"
+ ];
+
+ meta = with stdenv.lib; {
+ description = "Aggressive refactor of Vim";
+ homepage = http://www.neovim.org;
+ maintainers = with maintainers; [ manveru ];
+ platforms = platforms.unix;
+ };
+}
+
diff --git a/pkgs/applications/editors/netbeans/default.nix b/pkgs/applications/editors/netbeans/default.nix
index 5a2afebdd5c..79dbb589d23 100644
--- a/pkgs/applications/editors/netbeans/default.nix
+++ b/pkgs/applications/editors/netbeans/default.nix
@@ -26,8 +26,8 @@ stdenv.mkDerivation {
mkdir -p $out/bin
makeWrapper $out/netbeans/bin/netbeans $out/bin/netbeans \
--prefix PATH : ${jdk}/bin:${which}/bin \
- --prefix JAVA_HOME : ${jdk}/lib/openjdk \
- --add-flags "--jdkhome ${jdk}/lib/openjdk"
+ --prefix JAVA_HOME : ${jdk.home} \
+ --add-flags "--jdkhome ${jdk.home}"
# Create desktop item, so we can pick it from the KDE/GNOME menu
mkdir -p $out/share/applications
diff --git a/pkgs/applications/editors/nvi/default.nix b/pkgs/applications/editors/nvi/default.nix
index 81e0dd35db9..ee9b775453c 100644
--- a/pkgs/applications/editors/nvi/default.nix
+++ b/pkgs/applications/editors/nvi/default.nix
@@ -49,6 +49,6 @@ stdenv.mkDerivation rec {
meta = {
homepage = http://www.bostic.com/vi/;
description = "The Berkeley Vi Editor";
- license = "free";
+ license = stdenv.lib.licenses.free;
};
}
diff --git a/pkgs/applications/editors/rstudio/default.nix b/pkgs/applications/editors/rstudio/default.nix
new file mode 100644
index 00000000000..fda51dc2401
--- /dev/null
+++ b/pkgs/applications/editors/rstudio/default.nix
@@ -0,0 +1,71 @@
+{ stdenv, fetchurl, cmake, boost155, zlib, openssl, R, qt4, libuuid, hunspellDicts, unzip, ant, jdk }:
+
+let
+ version = "0.98.110";
+ ginVer = "1.5";
+ gwtVer = "2.5.1";
+in
+stdenv.mkDerivation {
+ name = "RStudio-${version}";
+
+ buildInputs = [ cmake boost155 zlib openssl R qt4 libuuid unzip ant jdk ];
+
+ src = fetchurl {
+ url = "https://github.com/rstudio/rstudio/archive/v${version}.tar.gz";
+ sha256 = "0wybbvl5libki8z2ywgcd0hg0py1az484r95lhwh3jbrwfx7ri2z";
+ };
+
+ # Hack RStudio to only use the input R.
+ patches = [ ./r-location.patch ];
+ postPatch = "substituteInPlace src/cpp/core/r_util/REnvironmentPosix.cpp --replace '@R@' ${R}";
+
+ inherit ginVer;
+ ginSrc = fetchurl {
+ url = "https://s3.amazonaws.com/rstudio-buildtools/gin-${ginVer}.zip";
+ sha256 = "155bjrgkf046b8ln6a55x06ryvm8agnnl7l8bkwwzqazbpmz8qgm";
+ };
+
+ inherit gwtVer;
+ gwtSrc = fetchurl {
+ url = "https://s3.amazonaws.com/rstudio-buildtools/gwt-${gwtVer}.zip";
+ sha256 = "0fjr2rcr8lnywj54mzhg9i4xz1b6fh8yv12p5i2q5mgfld2xymy4";
+ };
+
+ hunspellDicts = builtins.attrValues hunspellDicts;
+
+ mathJaxSrc = fetchurl {
+ url = https://s3.amazonaws.com/rstudio-buildtools/mathjax-20.zip;
+ sha256 = "1ikg3fhharsfrh2fv8c53fdawqajj24nif89400l3klw1hyq4zal";
+ };
+
+ preConfigure =
+ ''
+ GWT_LIB_DIR=src/gwt/lib
+
+ mkdir -p $GWT_LIB_DIR/gin/$ginVer
+ unzip $ginSrc -d $GWT_LIB_DIR/gin/$ginVer
+
+ unzip $gwtSrc
+ mkdir -p $GWT_LIB_DIR/gwt
+ mv gwt-$gwtVer $GWT_LIB_DIR/gwt/$gwtVer
+
+ mkdir dependencies/common/dictionaries
+ for dict in $hunspellDicts; do
+ for i in "$dict/share/hunspell/"*
+ do ln -sv $i dependencies/common/dictionaries/
+ done
+ done
+
+ unzip $mathJaxSrc -d dependencies/common/mathjax
+ '';
+
+ cmakeFlags = [ "-DRSTUDIO_TARGET=Desktop" ];
+
+ meta = with stdenv.lib;
+ { description = "Set of integrated tools for the R language";
+ homepage = http://www.rstudio.com/;
+ license = licenses.agpl3;
+ maintainers = [ maintainers.emery ];
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/editors/rstudio/r-location.patch b/pkgs/applications/editors/rstudio/r-location.patch
new file mode 100644
index 00000000000..a1ec84a5475
--- /dev/null
+++ b/pkgs/applications/editors/rstudio/r-location.patch
@@ -0,0 +1,24 @@
+diff -ur rstudio-0.98.110-old/src/cpp/core/CMakeLists.txt rstudio-0.98.110-new/src/cpp/core/CMakeLists.txt
+--- rstudio-0.98.110-old/src/cpp/core/r_util/REnvironmentPosix.cpp 2013-04-28 10:02:14.000000000 -0400
++++ rstudio-0.98.110-new/src/cpp/core/r_util/REnvironmentPosix.cpp 2015-03-23 15:06:35.533400807 -0400
+@@ -84,9 +84,7 @@
+ {
+ // define potential paths
+ std::vector rScriptPaths;
+- rScriptPaths.push_back("/usr/bin/R");
+- rScriptPaths.push_back("/usr/local/bin/R");
+- rScriptPaths.push_back("/opt/local/bin/R");
++ rScriptPaths.push_back("@R@/bin/R");
+ return scanForRScript(rScriptPaths, pErrMsg);
+ }
+
+@@ -220,8 +218,7 @@
+ // scan in standard locations as a fallback
+ std::string scanErrMsg;
+ std::vector rScriptPaths;
+- rScriptPaths.push_back("/usr/local/bin/R");
+- rScriptPaths.push_back("/usr/bin/R");
++ rScriptPaths.push_back("@R@/bin/R");
+ FilePath scriptPath = scanForRScript(rScriptPaths, &scanErrMsg);
+ if (scriptPath.empty())
+ {
diff --git a/pkgs/applications/editors/scite/default.nix b/pkgs/applications/editors/scite/default.nix
index 234ee1f065e..b2ac66c1e08 100644
--- a/pkgs/applications/editors/scite/default.nix
+++ b/pkgs/applications/editors/scite/default.nix
@@ -30,6 +30,6 @@ in stdenv.mkDerivation {
description = "SCIntilla based Text Editor";
license = stdenv.lib.licenses.mit;
platforms = stdenv.lib.platforms.linux;
- maintainers = stdenv.lib.maintainers.rszibele;
+ maintainers = [ stdenv.lib.maintainers.rszibele ];
};
}
diff --git a/pkgs/applications/editors/sigil/default.nix b/pkgs/applications/editors/sigil/default.nix
new file mode 100644
index 00000000000..2af662ded7f
--- /dev/null
+++ b/pkgs/applications/editors/sigil/default.nix
@@ -0,0 +1,66 @@
+{ stdenv, fetchurl, unzip, cmake, pkgconfig, makeWrapper
+, hunspell, minizip, boost, xercesc, qt5
+}:
+
+let
+ version = "0.7.4";
+
+in
+
+stdenv.mkDerivation rec {
+ name = "sigil-${version}";
+
+ src = fetchurl {
+ url = "https://sigil.googlecode.com/files/Sigil-${version}-Code.zip";
+ sha256 = "68c7ca15ea8611921af0c435369563f55c6afd2ef1fb0945cf6c4a47429b0fb5";
+ };
+
+ buildInputs = [
+ unzip cmake pkgconfig
+ hunspell minizip boost xercesc qt5.base qt5.tools qt5.webkit qt5.xmlpatterns
+ ];
+
+ # XXX: the compiler seems to treat the .h file inappropriately:
+ #
+ # COMMAND ${CMAKE_CXX_COMPILER} ${compile_flags} \
+ # ${CMAKE_CURRENT_SOURCE_DIR}/${header_name}.h \
+ # -o ${header_name}.h.gch
+ #
+ # but using -c or -x c++-header seems to work:
+ #
+ # COMMAND ${CMAKE_CXX_COMPILER} ${compile_flags} \
+ # -c ${CMAKE_CURRENT_SOURCE_DIR}/${header_name}.h \
+ # -o ${header_name}.h.gch
+ #
+ # COMMAND ${CMAKE_CXX_COMPILER} ${compile_flags} \
+ # -x c++-header ${CMAKE_CURRENT_SOURCE_DIR}/${header_name}.h \
+ # -o ${header_name}.h.gch
+ #
+ # Might be related to:
+ #
+ # http://permalink.gmane.org/gmane.comp.gcc.bugs/361195
+ buildCommand = ''
+ mkdir -pv $out
+ mkdir -pv ${name}/src ${name}/build ${name}/run
+ cd ${name}/src
+ unzip -n ${src}
+ sed -i \
+ -e 's|\(COMMAND\) \([^ ]\+\) \([^ ]\+\) \(.*\)|\1 \2 \3 -c \4|' \
+ cmake_extras/CustomPCH.cmake
+ cd ../build
+ cmake -G "Unix Makefiles" \
+ -DCMAKE_INSTALL_PREFIX=$out \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_SKIP_BUILD_RPATH=ON \
+ ../src
+ make
+ make install
+ '';
+
+ meta = {
+ description = "Free, open source, multi-platform ebook (ePub) editor";
+ homepage = https://code.google.com/p/sigil/;
+ license = stdenv.lib.licenses.gpl3;
+ inherit version;
+ };
+}
diff --git a/pkgs/applications/editors/sublime/default.nix b/pkgs/applications/editors/sublime/default.nix
index 0c967e05ba1..ffa1c4eed34 100644
--- a/pkgs/applications/editors/sublime/default.nix
+++ b/pkgs/applications/editors/sublime/default.nix
@@ -28,8 +28,8 @@ stdenv.mkDerivation rec {
echo ${libPath}
patchelf \
- --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
- --set-rpath ${libPath}:${stdenv.gcc.gcc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
+ --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+ --set-rpath ${libPath}:${stdenv.cc.cc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
$out/sublime/sublime_text
'';
diff --git a/pkgs/applications/editors/sublime3/default.nix b/pkgs/applications/editors/sublime3/default.nix
index 3ef557cef4b..1764c85ca7d 100644
--- a/pkgs/applications/editors/sublime3/default.nix
+++ b/pkgs/applications/editors/sublime3/default.nix
@@ -1,9 +1,9 @@
-{ fetchurl, stdenv, glib, xlibs, cairo, gtk, pango, makeWrapper}:
+{ fetchurl, stdenv, glib, xlibs, cairo, gtk, pango, makeWrapper, openssl, bzip2 }:
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
let
- build = "3059";
+ build = "3083";
libPath = stdenv.lib.makeLibraryPath [glib xlibs.libX11 gtk cairo pango];
in let
# package with just the binaries
@@ -13,15 +13,15 @@ in let
src =
if stdenv.system == "i686-linux" then
fetchurl {
- name = "sublimetext-3.0.59.tar.bz2";
+ name = "sublimetext-3.0.83.tar.bz2";
url = "http://c758482.r82.cf2.rackcdn.com/sublime_text_3_build_${build}_x32.tar.bz2";
- sha256 = "5ee7b42b5db057108e97b86fd408124fc3f7b56662b2851f59d91f8f0c288088";
+ sha256 = "0r9irk2gdwdx0dk7lgssr4krfvf3lf71pzaz5hyjc704zaxf5s49";
}
else
fetchurl {
- name = "sublimetext-3.0.59.tar.bz2";
+ name = "sublimetext-3.0.83.tar.bz2";
url = "http://c758482.r82.cf2.rackcdn.com/sublime_text_3_build_${build}_x64.tar.bz2";
- sha256 = "da3039687664d33a734cea0151b2291ece9c7f35e5b73df5b2b5eac28a20b972";
+ sha256 = "1vhlrqz7xscmjnxpz60mdpvflanl26d7673ml7psd75n0zvcfra5";
};
dontStrip = true;
@@ -31,17 +31,21 @@ in let
buildPhase = ''
for i in sublime_text plugin_host crash_reporter; do
patchelf \
- --interpreter "$(cat $NIX_GCC/nix-support/dynamic-linker)" \
- --set-rpath ${libPath}:${stdenv.gcc.gcc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
+ --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+ --set-rpath ${libPath}:${stdenv.cc.cc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"} \
$i
done
'';
installPhase = ''
+ # Correct sublime_text.desktop to exec `sublime' instead of /opt/sublime_text
+ sed -e 's,/opt/sublime_text/sublime_text,sublime,' -i sublime_text.desktop
+
mkdir -p $out
cp -prvd * $out/
+
# Without this, plugin_host crashes, even though it has the rpath
- wrapProgram $out/plugin_host --prefix LD_PRELOAD : ${stdenv.gcc.gcc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"}/libgcc_s.so.1
+ wrapProgram $out/plugin_host --prefix LD_PRELOAD : ${stdenv.cc.cc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"}/libgcc_s.so.1:${openssl}/lib/libssl.so:${bzip2}/lib/libbz2.so
'';
};
in stdenv.mkDerivation {
@@ -52,11 +56,16 @@ in stdenv.mkDerivation {
mkdir -p $out/bin
ln -s ${sublime}/sublime_text $out/bin/sublime
ln -s ${sublime}/sublime_text $out/bin/sublime3
+ mkdir -p $out/share/applications
+ ln -s ${sublime}/sublime_text.desktop $out/share/applications/sublime_text.desktop
+ ln -s ${sublime}/Icon/256x256/ $out/share/icons
'';
- meta = {
+ meta = with stdenv.lib; {
description = "Sophisticated text editor for code, markup and prose";
- maintainers = stdenv.lib.maintainers.wmertens;
- license = stdenv.lib.licenses.unfree;
+ homepage = https://www.sublimetext.com/;
+ maintainers = with maintainers; [ wmertens ];
+ license = licenses.unfree;
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/applications/editors/texmaker/default.nix b/pkgs/applications/editors/texmaker/default.nix
index 16335a55065..4df2dc8cac1 100644
--- a/pkgs/applications/editors/texmaker/default.nix
+++ b/pkgs/applications/editors/texmaker/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl, qt4, popplerQt4, zlib, pkgconfig, poppler}:
+{ stdenv, fetchurl, qt4, poppler_qt4, zlib, pkgconfig, poppler}:
stdenv.mkDerivation rec {
pname = "texmaker";
@@ -10,7 +10,7 @@ stdenv.mkDerivation rec {
sha256 = "1h5rxdq6f05wk3lnlw96fxwrb14k77cx1mwy648127h2c8nsgw4z";
};
- buildInputs = [ qt4 popplerQt4 zlib ];
+ buildInputs = [ qt4 poppler_qt4 zlib ];
nativeBuildInputs = [ pkgconfig poppler ];
diff --git a/pkgs/applications/editors/texstudio/default.nix b/pkgs/applications/editors/texstudio/default.nix
index cd7f0b78c23..5cb31af797d 100644
--- a/pkgs/applications/editors/texstudio/default.nix
+++ b/pkgs/applications/editors/texstudio/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchurl, qt4, popplerQt4, zlib}:
+{ stdenv, fetchurl, qt4, poppler_qt4, zlib}:
stdenv.mkDerivation rec {
pname = "texstudio";
@@ -11,10 +11,10 @@ stdenv.mkDerivation rec {
sha256 = "167d78nfk265jjvl129nr70v8ladb2rav2qyhw7ngr6m54gak831";
};
- buildInputs = [ qt4 popplerQt4 zlib ];
+ buildInputs = [ qt4 poppler_qt4 zlib ];
preConfigure = ''
- export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I$(echo ${popplerQt4}/include/poppler/qt4) "
+ export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I$(echo ${poppler_qt4}/include/poppler/qt4) "
qmake PREFIX=$out texstudio.pro
'';
diff --git a/pkgs/applications/editors/tiled-qt/default.nix b/pkgs/applications/editors/tiled-qt/default.nix
deleted file mode 100644
index 05020df01a0..00000000000
--- a/pkgs/applications/editors/tiled-qt/default.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-{ stdenv, fetchurl, qt }:
-
-stdenv.mkDerivation rec {
- name = "tiled-qt-0.9.1";
-
- src = fetchurl {
- url = "mirror://sourceforge/tiled/${name}.tar.gz";
- sha256 = "09xm6ry56zsqbfl9fvlvc5kq9ikzdskm283r059q6rlc7crzhs38";
- };
-
- buildInputs = [ qt ];
-
- preConfigure = "qmake -r PREFIX=$out";
-
- meta = {
- description = "A free, easy to use and flexible tile map editor";
- homepage = "http://www.mapeditor.org/";
- # libtiled and tmxviewer is licensed under 2-calause BSD license.
- # The rest is GPL2 or later.
- license = stdenv.lib.licenses.gpl2Plus;
- platforms = stdenv.lib.platforms.linux;
- maintainers = with stdenv.lib.maintainers; [ iyzsong ];
- };
-}
diff --git a/pkgs/applications/editors/tiled/default.nix b/pkgs/applications/editors/tiled/default.nix
new file mode 100644
index 00000000000..92cd5071306
--- /dev/null
+++ b/pkgs/applications/editors/tiled/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchurl, qt }:
+
+stdenv.mkDerivation rec {
+ name = "tiled-0.11.0";
+
+ src = fetchurl {
+ url = "https://github.com/bjorn/tiled/archive/v0.11.0.tar.gz";
+ sha256 = "03a15vbzjfwc8dpifbjvd0gnr208mzmdkgs2nlc8zq6z0a4h4jqd";
+ };
+
+ buildInputs = [ qt ];
+
+ preConfigure = "qmake -r PREFIX=$out";
+
+ meta = {
+ description = "A free, easy to use and flexible tile map editor";
+ homepage = "http://www.mapeditor.org/";
+ # libtiled and tmxviewer is licensed under 2-calause BSD license.
+ # The rest is GPL2 or later.
+ license = stdenv.lib.licenses.gpl2Plus;
+ platforms = stdenv.lib.platforms.linux;
+ maintainers = with stdenv.lib.maintainers; [ iyzsong ];
+ };
+}
diff --git a/pkgs/applications/editors/vanubi/default.nix b/pkgs/applications/editors/vanubi/default.nix
new file mode 100644
index 00000000000..692a728b12e
--- /dev/null
+++ b/pkgs/applications/editors/vanubi/default.nix
@@ -0,0 +1,28 @@
+{ stdenv, fetchurl, pkgconfig, vala, which, autoconf, automake
+, libtool, glib, gtk3, gnome3, libwnck3, asciidoc, python3Packages }:
+
+stdenv.mkDerivation rec {
+ name = "vanubi-${version}";
+ version = "0.0.14";
+
+ src = fetchurl {
+ url = "https://github.com/vanubi/vanubi/archive/v${version}.tar.gz";
+ sha256 = "0cd45zm54j6xz1a31qllg2w7l77sncv7mrpfx9bjzdiqpmzsdypl";
+ };
+
+ buildInputs = [ pkgconfig vala which autoconf automake
+ libtool glib gtk3 libwnck3 asciidoc
+ gnome3.gtksourceview gnome3.vte python3Packages.pygments ];
+
+ configureScript = "./autogen.sh";
+
+ enableParallelBuilding = true;
+
+ meta = with stdenv.lib; {
+ homepage = http://vanubi.github.io/vanubi;
+ description = "Programming editor for GTK+ inspired by Emacs";
+ license = licenses.gpl3;
+ platforms = platforms.linux;
+ maintainers = [ maintainers.lethalman ];
+ };
+}
diff --git a/pkgs/applications/editors/vim/configurable.nix b/pkgs/applications/editors/vim/configurable.nix
index 710ceb7d31f..e6c2cacc49a 100644
--- a/pkgs/applications/editors/vim/configurable.nix
+++ b/pkgs/applications/editors/vim/configurable.nix
@@ -31,13 +31,9 @@ let inherit (args.composableDerivation) composableDerivation edf;
'';
in
composableDerivation {
- # use gccApple to compile on darwin
- mkDerivation = ( if stdenv.isDarwin
- then stdenvAdapters.overrideGCC stdenv gccApple
- else stdenv ).mkDerivation;
} (fix: {
- name = "vim_configurable-7.4.335";
+ name = "vim_configurable-7.4.516";
enableParallelBuilding = true; # test this
@@ -46,9 +42,9 @@ composableDerivation {
"default" =
# latest release
args.fetchhg {
- url = "https://vim.googlecode.com/hg/";
- rev = "v7-4-335";
- sha256 = "0qnpzfcbi6fhz82pj68l4vrnigca1akq2ksrxz6krwlfhns6jhhj";
+ url = "http://vim.googlecode.com/hg/";
+ rev = "v7-4-516";
+ sha256 = "0a3b5qaywfn7jjr7fjpl8y8jx4wjj2630wxfjnmn3hi1l7iiz4z8";
};
"vim-nox" =
@@ -91,7 +87,7 @@ composableDerivation {
// edf { name = "darwin"; } #Disable Darwin (Mac OS X) support.
// edf { name = "xsmp"; } #Disable XSMP session management
// edf { name = "xsmp_interact"; } #Disable XSMP interaction
- // edf { name = "mzscheme"; } #Include MzScheme interpreter.
+ // edf { name = "mzscheme"; feat = "mzschemeinterp";} #Include MzScheme interpreter.
// edf { name = "perl"; feat = "perlinterp"; enable = { nativeBuildInputs = [perl]; };} #Include Perl interpreter.
// edf {
@@ -106,7 +102,20 @@ composableDerivation {
};
}
- // edf { name = "tcl"; enable = { nativeBuildInputs = [tcl]; }; } #Include Tcl interpreter.
+ // edf {
+ name = "python3";
+ feat = "python3interp";
+ enable = {
+ nativeBuildInputs = [ pkgs.python3 ];
+ } // lib.optionalAttrs stdenv.isDarwin {
+ configureFlags
+ = [ "--enable-python3interp=yes"
+ "--with-python3-config-dir=${pkgs.python3}/lib"
+ "--disable-pythoninterp" ];
+ };
+ }
+
+ // edf { name = "tcl"; feat = "tclinterp"; enable = { nativeBuildInputs = [tcl]; }; } #Include Tcl interpreter.
// edf { name = "ruby"; feat = "rubyinterp"; enable = { nativeBuildInputs = [ruby]; };} #Include Ruby interpreter.
// edf {
name = "lua";
@@ -135,11 +144,12 @@ composableDerivation {
cfg = {
luaSupport = config.vim.lua or true;
pythonSupport = config.vim.python or true;
+ python3Support = config.vim.python3 or false;
rubySupport = config.vim.ruby or true;
nlsSupport = config.vim.nls or false;
tclSupport = config.vim.tcl or false;
multibyteSupport = config.vim.multibyte or false;
- cscopeSupport = config.vim.cscope or false;
+ cscopeSupport = config.vim.cscope or true;
netbeansSupport = config.netbeans or true; # eg envim is using it
# by default, compile with darwin support if we're compiling on darwin, but
diff --git a/pkgs/applications/editors/vim/default.nix b/pkgs/applications/editors/vim/default.nix
index 95f654eb8ca..4f14aade5a5 100644
--- a/pkgs/applications/editors/vim/default.nix
+++ b/pkgs/applications/editors/vim/default.nix
@@ -3,12 +3,12 @@
stdenv.mkDerivation rec {
name = "vim-${version}";
- version = "7.4.335";
+ version = "7.4.683";
src = fetchhg {
- url = "https://vim.googlecode.com/hg/";
- rev = "v7-4-335";
- sha256 = "0qnpzfcbi6fhz82pj68l4vrnigca1akq2ksrxz6krwlfhns6jhhj";
+ url = "https://code.google.com/p/vim/";
+ rev = "v7-4-663";
+ sha256 = "1z0qarf6a2smab28g9dnxklhfayn85wx48bnddmyhb9kqzjgqgjc";
};
enableParallelBuilding = true;
diff --git a/pkgs/applications/editors/vim/ft-nix-support.patch b/pkgs/applications/editors/vim/ft-nix-support.patch
index ed508784813..cbbe1ccb212 100644
--- a/pkgs/applications/editors/vim/ft-nix-support.patch
+++ b/pkgs/applications/editors/vim/ft-nix-support.patch
@@ -23,39 +23,42 @@ new file mode 100644
index 0000000..a2f9918
--- /dev/null
+++ b/runtime/syntax/nix.vim
-@@ -0,0 +1,47 @@
+@@ -0,0 +1,56 @@
+" Vim syntax file
+" Language: nix
+" Maintainer: Marc Weber
+" Modify and commit if you feel that way
-+" Last Change: 2007 Dec
++" Last Change: 2011 Jun
+"
+" this syntax file can be still be enhanced very much..
+" Don't ask, do it :-)
++" This file (github.com/MarcWeber/vim-addon-nix) is periodically synced with
++" the patch found in vim_configurable (nixpkgs)
+
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
+ finish
+endif
+
-+syn keyword nixKeyword let in rec assert inherit import true false null with ...
-+syn keyword nixBuiltin import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation
++
++sy cluster nixStrings contains=nixStringParam,nixStringIndented
++
++syn keyword nixKeyword let throw inherit import true false null with
+syn keyword nixConditional if else then
+syn keyword nixBrace ( ) { } =
+syn keyword nixBuiltin __currentSystem __currentTime __isFunction __getEnv __trace __toPath __pathExists
+ \ __readFile __toXML __toFile __filterSource __attrNames __getAttr __hasAttr __isAttrs __listToAttrs __isList
+ \ __head __tail __add __sub __lessThan __substring __stringLength
+
-+syn match nixAttr "[a-zA-Z0-9-_]\+\ze\s*="
-+syn match nixFuncArg "\zs[a-zA-Z0-9-_]\+\ze\s*:"
-+syn region nixStringParam start=+\${+ end=+}+
++syn region nixStringIndented start=+''+ skip=+'''\|''${\|"+ end=+''+ contains=nixStringParam
++" syn region nixString start=+"+ skip=+\\"+ end=+"+
++syn match nixAttr "\w\+\ze\s*="
++syn match nixFuncArg "\zs\w\+\ze\s*:"
++syn region nixStringParam start=+\${+ end=+}+ contains=@nixStrings
+syn region nixMultiLineComment start=+/\*+ skip=+\\"+ end=+\*/+
+syn match nixEndOfLineComment "#.*$"
-+syn region nixStringIndented start=+''+ skip=+'''\|''${\|"+ end=+''+ contains=nixStringParam
-+syn region nixString start=+"+ skip=+\\"+ end=+"+ contains=nixStringParam
+
+hi def link nixKeyword Keyword
-+hi def link nixBuiltin Function
+hi def link nixConditional Conditional
+hi def link nixBrace Special
+hi def link nixString String
@@ -67,9 +70,20 @@ index 0000000..a2f9918
+hi def link nixAttr Identifier
+hi def link nixFuncArg Identifier
+
++syn sync maxlines=20000
++syn sync minlines=50000
++
+let b:current_syntax = "nix"
+
++" thanks to iElectric
+" scan backwards to find begining of multiline statements
+syn sync ccomment nixMultiLineComment minlines=10 maxlines=500
+syn sync ccomment nixStringIndented minlines=10 maxlines=500
+syn sync ccomment nixString maxlines=10
+diff --git a/runtime/ftplugin/nix.vim b/runtime/ftplugin/nix.vim
+new file mode 100644
+--- /dev/null
++++ b/runtime/ftplugin/nix.vim
+@@ -0,0 +1,2 @@
++" coding conventions
++setlocal sw=2 ts=2 expandtab
diff --git a/pkgs/applications/editors/vim/macvim.nix b/pkgs/applications/editors/vim/macvim.nix
index feafa7b9977..784be80ecf4 100644
--- a/pkgs/applications/editors/vim/macvim.nix
+++ b/pkgs/applications/editors/vim/macvim.nix
@@ -1,18 +1,15 @@
-{ stdenv, stdenvAdapters, gccApple, fetchFromGitHub, ncurses, gettext,
+{ stdenv, fetchurl, ncurses, gettext,
pkgconfig, cscope, python, ruby, tcl, perl, luajit
}:
-let inherit (stdenvAdapters.overrideGCC stdenv gccApple) mkDerivation;
-in mkDerivation rec {
+stdenv.mkDerivation rec {
name = "macvim-${version}";
- version = "7.4.355";
+ version = "7.4.479";
- src = fetchFromGitHub {
- owner = "genoma";
- repo = "macvim";
- rev = "c18a61f9723565664ffc2eda9179e96c95860e25";
- sha256 = "190bngg8m4bwqcia7w24gn7mmqkhk0mavxy81ziwysam1f652ymf";
+ src = fetchurl {
+ url = "https://github.com/genoma/macvim/archive/g-snapshot-21.tar.gz";
+ sha256 = "1s86dpb8bcxh309gikiz8gm9ygv3d2jy6i4qlnxarbvcdk65fzv4";
};
enableParallelBuilding = true;
@@ -46,6 +43,7 @@ in mkDerivation rec {
"--enable-perlinterp=dynamic"
"--enable-rubyinterp=dynamic"
"--enable-tclinterp=yes"
+ "--without-local-dir"
"--with-luajit"
"--with-lua-prefix=${luajit}"
"--with-ruby-command=${ruby}/bin/ruby"
@@ -54,6 +52,8 @@ in mkDerivation rec {
"--with-compiledby=Nix"
];
+ makeFlags = ''PREFIX=$(out) CPPFLAGS="-Wno-error"'';
+
preConfigure = ''
DEV_DIR=$(/usr/bin/xcode-select -print-path)/Platforms/MacOSX.platform/Developer
configureFlagsArray+=(
diff --git a/pkgs/applications/editors/vim/macvim.patch b/pkgs/applications/editors/vim/macvim.patch
index a789b9952d2..a42ebd4cc03 100644
--- a/pkgs/applications/editors/vim/macvim.patch
+++ b/pkgs/applications/editors/vim/macvim.patch
@@ -187,3 +187,36 @@ index bc9f074..9b9125e 100755
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
$ac_cs_success || as_fn_exit 1
+
+diff --git a/src/Makefile b/src/Makefile
+index 1c4d104..fff2015 100644
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -1298,7 +1298,7 @@ MACVIMGUI_SRC = gui.c gui_beval.c MacVim/gui_macvim.m MacVim/MMBackend.m \
+ MacVim/MacVim.m
+ MACVIMGUI_OBJ = objects/gui.o objects/gui_beval.o objects/pty.o \
+ objects/gui_macvim.o objects/MMBackend.o objects/MacVim.o
+-MACVIMGUI_DEFS = -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe
++MACVIMGUI_DEFS = -DMACOS_X_UNIX -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe
+ MACVIMGUI_IPATH =
+ MACVIMGUI_LIBS_DIR =
+ MACVIMGUI_LIBS1 = -framework Cocoa -framework Carbon
+
+diff --git a/src/if_python.c b/src/if_python.c
+index b356bf7..b7bfa78 100644
+--- a/src/if_python.c
++++ b/src/if_python.c
+@@ -55,11 +55,7 @@
+
+ #define PY_SSIZE_T_CLEAN
+
+-#ifdef FEAT_GUI_MACVIM
+-# include
+-#else
+-# include
+-#endif
++#include
+
+ #if !defined(PY_VERSION_HEX) || PY_VERSION_HEX < 0x02050000
+ # undef PY_SSIZE_T_CLEAN
+ MACVIMGUI_LIBS1 = -framework Cocoa -framework Carbon
diff --git a/pkgs/applications/editors/vim/qvim.nix b/pkgs/applications/editors/vim/qvim.nix
index 2357e23bf01..b9e3d668d62 100644
--- a/pkgs/applications/editors/vim/qvim.nix
+++ b/pkgs/applications/editors/vim/qvim.nix
@@ -1,22 +1,21 @@
args@{...}: with args;
+let tag = "20140827";
+ sha256 = "02adf2212872db3c5d133642d2c12fbfc28b506e4c0c42552e3d079756f63f65";
+in
let inherit (args.composableDerivation) composableDerivation edf; in
composableDerivation {
- # use gccApple to compile on darwin
- mkDerivation = ( if stdenv.isDarwin
- then stdenvAdapters.overrideGCC stdenv gccApple
- else stdenv ).mkDerivation;
} (fix: {
- name = "qvim-7.4";
+ name = "qvim-7.4." + tag;
enableParallelBuilding = true; # test this
src = fetchgit {
url = https://bitbucket.org/equalsraf/vim-qt.git ;
- rev = "4160bfd5c1380e899d2f426b494fc4f1cf6ae85e";
- sha256 = "1qa3xl1b9gqw66p71h53l7ibs4y3zfyj553jss70ybxaxchbhi5b";
+ rev = "refs/tags/package-" + tag;
+ inherit sha256;
};
# FIXME: adopt Darwin fixes from vim/default.nix, then chage meta.platforms.linux
@@ -119,7 +118,7 @@ composableDerivation {
meta = with stdenv.lib; {
description = "The most popular clone of the VI editor (Qt GUI fork)";
homepage = https://bitbucket.org/equalsraf/vim-qt/wiki/Home;
- maintainers = with maintainers; [ smironov ];
+ maintainers = with maintainers; [ smironov ttuegel ];
platforms = platforms.linux;
};
})
diff --git a/pkgs/applications/editors/wxhexeditor/default.nix b/pkgs/applications/editors/wxhexeditor/default.nix
new file mode 100644
index 00000000000..de423987c02
--- /dev/null
+++ b/pkgs/applications/editors/wxhexeditor/default.nix
@@ -0,0 +1,41 @@
+{ stdenv, fetchurl, wxGTK, autoconf, automake, libtool, python, gettext, bash }:
+
+stdenv.mkDerivation rec {
+ name = "wxHexEditor-${version}";
+ version = "v0.22";
+
+ src = fetchurl {
+ url = "mirror://sourceforge/wxhexeditor/${name}-src.tar.bz2";
+ sha256 = "15ir038g4lyw1q5bsay974hvj0nkg2yd9kccwxz808cd45fp411w";
+ };
+
+ buildInputs = [ wxGTK autoconf automake libtool python gettext ];
+
+ patchPhase = ''
+ substituteInPlace Makefile --replace "/usr/local" "$out"
+ substituteInPlace Makefile --replace "mhash; ./configure" "mhash; ./configure --prefix=$out"
+ substituteInPlace udis86/autogen.sh --replace "/bin/bash" "${bash}/bin/bash"
+ '';
+
+ buildPhase = ''
+ make OPTFLAGS="-fopenmp"
+
+ '';
+
+ meta = {
+ description = "Hex Editor / Disk Editor for Huge Files or Devices";
+ longDescription = ''
+ This is not an ordinary hex editor, but could work as low level disk editor too.
+ If you have problems with your HDD or partition, you can recover your data from HDD or
+ from partition via editing sectors in raw hex.
+ You can edit your partition tables or you could recover files from File System by hand
+ with help of wxHexEditor.
+ Or you might want to analyze your big binary files, partitions, devices... If you need
+ a good reverse engineer tool like a good hex editor, you welcome.
+ wxHexEditor could edit HDD/SDD disk devices or partitions in raw up to exabyte sizes.
+ '';
+ homepage = "http://www.wxhexeditor.org/";
+ license = stdenv.lib.licenses.gpl2;
+ platforms = stdenv.lib.platforms.linux;
+ };
+}
diff --git a/pkgs/applications/editors/yi/yi-contrib.nix b/pkgs/applications/editors/yi/yi-contrib.nix
deleted file mode 100644
index 2678f0a0048..00000000000
--- a/pkgs/applications/editors/yi/yi-contrib.nix
+++ /dev/null
@@ -1,21 +0,0 @@
-# This file was auto-generated by cabal2nix. Please do NOT edit manually!
-
-{ cabal, filepath, lens, mtl, split, time, transformersBase, yi }:
-
-cabal.mkDerivation (self: {
- pname = "yi-contrib";
- version = "0.8.2";
- sha256 = "17rbgrra1ghlywiraadf16n7igxp1k8jqqmb0iw8sc15y7825qqm";
- buildDepends = [
- filepath lens mtl split time transformersBase yi
- ];
- meta = {
- homepage = "http://haskell.org/haskellwiki/Yi";
- description = "Add-ons to Yi, the Haskell-Scriptable Editor";
- license = "GPL";
- broken = true;
- platforms = self.ghc.meta.platforms;
- hydraPlatforms = self.stdenv.lib.platforms.none;
- maintainers = with self.stdenv.lib.maintainers; [ fuuzetsu ];
- };
-})
diff --git a/pkgs/applications/editors/yi/yi-custom-cabal/LICENSE b/pkgs/applications/editors/yi/yi-custom-cabal/LICENSE
new file mode 100644
index 00000000000..cf1ab25da03
--- /dev/null
+++ b/pkgs/applications/editors/yi/yi-custom-cabal/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to
diff --git a/pkgs/applications/editors/yi/yi-custom-cabal/yi-custom.cabal b/pkgs/applications/editors/yi/yi-custom-cabal/yi-custom.cabal
new file mode 100644
index 00000000000..d9ffbb8e481
--- /dev/null
+++ b/pkgs/applications/editors/yi/yi-custom-cabal/yi-custom.cabal
@@ -0,0 +1,17 @@
+name: yi-custom
+version: 0.0.0.1
+category: Yi
+synopsis: Convenience wrapper for nix
+description: Convenience wrapper for nix
+license: PublicDomain
+license-file: LICENSE
+author: Mateusz Kowalczyk
+maintainer: fuuzetsu@fuuzetsu.co.uk
+Cabal-Version: >= 1.10
+build-type: Simple
+
+library
+ hs-source-dirs: .
+ default-language: Haskell2010
+ build-depends: base, yi
+ ghc-options: -threaded
diff --git a/pkgs/applications/editors/yi/yi-custom.nix b/pkgs/applications/editors/yi/yi-custom.nix
new file mode 100644
index 00000000000..3dbd4611998
--- /dev/null
+++ b/pkgs/applications/editors/yi/yi-custom.nix
@@ -0,0 +1,40 @@
+# This is a manually-written expression over an in-tree cabal file.
+# It's awkward but this way allows the package user to pass in
+# extraPackages without much extra hassle on their end, similarly how
+# the XMonad service handles it: the difference is that we don't have
+# anything like XMONAD_GHC…
+#
+# The idea is that the user changes their configs using any libraries
+# he likes and then builds it using this expression. Once that's done,
+# ‘reload’ and similar functions should all work as long as the user
+# doesn't need new libraries at which point they should add them to
+# extraPackages and rebuild from the expression.
+{ cabal, yi, extraPackages, makeWrapper, ghcWithPackages }:
+let
+ w = ghcWithPackages (self: [ yi ] ++ extraPackages self);
+ wrappedGhc = w.override { ignoreCollisions = true; };
+in
+cabal.mkDerivation (self: rec {
+ pname = "yi-custom";
+ version = "0.0.0.1";
+ src = ./yi-custom-cabal;
+ isLibrary = true;
+ buildDepends = [ yi ];
+ buildTools = [ makeWrapper ];
+ noHaddock = true;
+ doCheck = false;
+
+ postInstall = ''
+ makeWrapper ${yi}/bin/yi $out/bin/yi \
+ --set NIX_GHC ${wrappedGhc}/bin/ghc \
+ --set NIX_GHC_LIBDIR ${wrappedGhc}/lib/ghc-${self.ghc.version}
+ '';
+ meta = {
+ homepage = "http://haskell.org/haskellwiki/Yi";
+ description = "Wrapper over user-specified Haskell libraries for use in Yi config";
+ license = self.stdenv.lib.licenses.publicDomain;
+ platforms = self.ghc.meta.platforms;
+ maintainers = with self.stdenv.lib.maintainers; [ fuuzetsu ];
+ };
+
+})
\ No newline at end of file
diff --git a/pkgs/applications/editors/yi/yi.nix b/pkgs/applications/editors/yi/yi.nix
index 9b9287a50f1..a63375adfd1 100644
--- a/pkgs/applications/editors/yi/yi.nix
+++ b/pkgs/applications/editors/yi/yi.nix
@@ -1,65 +1,39 @@
-{ cabal, alex, binary, Cabal, cautiousFile, concreteTyperep
-, dataDefault, derive, Diff, dlist, dyre, filepath, fingertree
-, glib, gtk, hashable, hint, HUnit, lens, mtl, pango, parsec
-, pointedlist, QuickCheck, random, regexBase, regexTdfa, safe
-, split, tasty, tastyHunit, tastyQuickcheck, time, transformersBase
-, uniplate, unixCompat, unorderedContainers, utf8String, vty
-, xdgBasedir
-, withPango ? true
+# This file was auto-generated by cabal2nix. Please do NOT edit manually!
-# User may need extra dependencies for their configuration file so we
-# want to specify it here to have them available when wrapping the
-# produced binary.
-, extraDepends ? [ ]
+{ cabal, binary, Cabal, cautiousFile, dataDefault, derive, dlist
+, dynamicState, dyre, exceptions, filepath, glib, gtk, hashable
+, hint, HUnit, lens, mtl, ooPrototypes, pango, parsec, pointedlist
+, QuickCheck, random, regexBase, regexTdfa, safe, semigroups, split
+, tagged, tasty, tastyHunit, tastyQuickcheck, text, time
+, transformersBase, unixCompat, unorderedContainers, utf8String
+, vty, wordTrie, xdgBasedir, yiLanguage, yiRope
}:
cabal.mkDerivation (self: {
pname = "yi";
- version = "0.8.2";
- sha256 = "18rnyswsdzkh0jdcqfg8pr90mpm6xf11siv598svqkxg12d2qql9";
+ version = "0.11.1";
+ sha256 = "15m1wwrxmszl930az79lpgyz5rxg72gy8vi17ibpac1cszfdx192";
isLibrary = true;
isExecutable = true;
buildDepends = [
- binary Cabal cautiousFile concreteTyperep dataDefault derive Diff
- dlist dyre filepath fingertree hashable hint lens mtl
- parsec pointedlist QuickCheck random regexBase regexTdfa safe
- split time transformersBase uniplate unixCompat unorderedContainers
- utf8String vty xdgBasedir
- ] ++ (if withPango then [ pango gtk glib ] else [ ]) ++ extraDepends;
- testDepends = [
- filepath HUnit QuickCheck tasty tastyHunit tastyQuickcheck
+ binary Cabal cautiousFile dataDefault derive dlist dynamicState
+ dyre exceptions filepath glib gtk hashable hint lens mtl
+ ooPrototypes pango parsec pointedlist QuickCheck random regexBase
+ regexTdfa safe semigroups split tagged text time transformersBase
+ unixCompat unorderedContainers utf8String vty wordTrie xdgBasedir
+ yiLanguage yiRope
];
- buildTools = [ alex ];
- configureFlags = if withPango then "-fpango" else "-f-pango";
- doCheck = false;
-
- # https://ghc.haskell.org/trac/ghc/ticket/9170
- noHaddock = self.ghc.version == "7.6.3";
-
- # Allows Yi to find the libraries it needs at runtime.
- postInstall = ''
- mv $out/bin/yi $out/bin/.yi-wrapped
- cat - > $out/bin/yi <=0.2.0" =
- self.by-version."punycode"."1.3.0";
- by-version."punycode"."1.3.0" = lib.makeOverridable self.buildNodePackage {
- name = "node-punycode-1.3.0";
+ by-spec."on-finished"."2.1.0" =
+ self.by-version."on-finished"."2.1.0";
+ by-version."on-finished"."2.1.0" = lib.makeOverridable self.buildNodePackage {
+ name = "node-on-finished-2.1.0";
src = [
(fetchurl {
- url = "http://registry.npmjs.org/punycode/-/punycode-1.3.0.tgz";
- name = "punycode-1.3.0.tgz";
- sha1 = "7f5009ef539b9444be5c7a19abd2c3ca49e1731c";
+ url = "http://registry.npmjs.org/on-finished/-/on-finished-2.1.0.tgz";
+ name = "on-finished-2.1.0.tgz";
+ sha1 = "0c539f09291e8ffadde0c8a25850fb2cedc7022d";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."on-finished" or []);
+ deps = [
+ self.by-version."ee-first"."1.0.5"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "on-finished" ];
+ };
+ by-spec."on-finished"."~2.1.0" =
+ self.by-version."on-finished"."2.1.0";
+ by-spec."options".">=0.0.5" =
+ self.by-version."options"."0.0.6";
+ by-version."options"."0.0.6" = lib.makeOverridable self.buildNodePackage {
+ name = "node-options-0.0.6";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/options/-/options-0.0.6.tgz";
+ name = "options-0.0.6.tgz";
+ sha1 = "ec22d312806bb53e731773e7cdaefcf1c643128f";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."options" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "options" ];
+ };
+ by-spec."parseurl"."~1.3.0" =
+ self.by-version."parseurl"."1.3.0";
+ by-version."parseurl"."1.3.0" = lib.makeOverridable self.buildNodePackage {
+ name = "node-parseurl-1.3.0";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz";
+ name = "parseurl-1.3.0.tgz";
+ sha1 = "b58046db4223e145afa76009e61bac87cc2281b3";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."parseurl" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "parseurl" ];
+ };
+ by-spec."path-to-regexp"."0.1.3" =
+ self.by-version."path-to-regexp"."0.1.3";
+ by-version."path-to-regexp"."0.1.3" = lib.makeOverridable self.buildNodePackage {
+ name = "node-path-to-regexp-0.1.3";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.3.tgz";
+ name = "path-to-regexp-0.1.3.tgz";
+ sha1 = "21b9ab82274279de25b156ea08fd12ca51b8aecb";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."path-to-regexp" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "path-to-regexp" ];
+ };
+ by-spec."proxy-addr"."~1.0.3" =
+ self.by-version."proxy-addr"."1.0.3";
+ by-version."proxy-addr"."1.0.3" = lib.makeOverridable self.buildNodePackage {
+ name = "node-proxy-addr-1.0.3";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.3.tgz";
+ name = "proxy-addr-1.0.3.tgz";
+ sha1 = "17d824aac844707441249da6d1ea5e889007cdd6";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."proxy-addr" or []);
+ deps = [
+ self.by-version."forwarded"."0.1.0"
+ self.by-version."ipaddr.js"."0.1.3"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "proxy-addr" ];
+ };
+ by-spec."punycode".">=0.2.0" =
+ self.by-version."punycode"."1.3.1";
+ by-version."punycode"."1.3.1" = lib.makeOverridable self.buildNodePackage {
+ name = "node-punycode-1.3.1";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/punycode/-/punycode-1.3.1.tgz";
+ name = "punycode-1.3.1.tgz";
+ sha1 = "710afe5123c20a1530b712e3e682b9118fe8058e";
})
];
buildInputs =
@@ -479,6 +1175,25 @@
];
passthru.names = [ "punycode" ];
};
+ by-spec."qs"."2.2.4" =
+ self.by-version."qs"."2.2.4";
+ by-version."qs"."2.2.4" = lib.makeOverridable self.buildNodePackage {
+ name = "node-qs-2.2.4";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/qs/-/qs-2.2.4.tgz";
+ name = "qs-2.2.4.tgz";
+ sha1 = "2e9fbcd34b540e3421c924ecd01e90aa975319c8";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."qs" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "qs" ];
+ };
by-spec."qs"."~0.6.0" =
self.by-version."qs"."0.6.6";
by-version."qs"."0.6.6" = lib.makeOverridable self.buildNodePackage {
@@ -498,6 +1213,46 @@
];
passthru.names = [ "qs" ];
};
+ by-spec."range-parser"."~1.0.2" =
+ self.by-version."range-parser"."1.0.2";
+ by-version."range-parser"."1.0.2" = lib.makeOverridable self.buildNodePackage {
+ name = "node-range-parser-1.0.2";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/range-parser/-/range-parser-1.0.2.tgz";
+ name = "range-parser-1.0.2.tgz";
+ sha1 = "06a12a42e5131ba8e457cd892044867f2344e549";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."range-parser" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "range-parser" ];
+ };
+ by-spec."raw-body"."1.3.0" =
+ self.by-version."raw-body"."1.3.0";
+ by-version."raw-body"."1.3.0" = lib.makeOverridable self.buildNodePackage {
+ name = "node-raw-body-1.3.0";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/raw-body/-/raw-body-1.3.0.tgz";
+ name = "raw-body-1.3.0.tgz";
+ sha1 = "978230a156a5548f42eef14de22d0f4f610083d1";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."raw-body" or []);
+ deps = [
+ self.by-version."bytes"."1.0.0"
+ self.by-version."iconv-lite"."0.4.4"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "raw-body" ];
+ };
by-spec."request"."~2.34.0" =
self.by-version."request"."2.34.0";
by-version."request"."2.34.0" = lib.makeOverridable self.buildNodePackage {
@@ -549,6 +1304,58 @@
];
passthru.names = [ "rimraf" ];
};
+ by-spec."send"."0.9.3" =
+ self.by-version."send"."0.9.3";
+ by-version."send"."0.9.3" = lib.makeOverridable self.buildNodePackage {
+ name = "node-send-0.9.3";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/send/-/send-0.9.3.tgz";
+ name = "send-0.9.3.tgz";
+ sha1 = "b43a7414cd089b7fbec9b755246f7c37b7b85cc0";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."send" or []);
+ deps = [
+ self.by-version."debug"."2.0.0"
+ self.by-version."depd"."0.4.5"
+ self.by-version."destroy"."1.0.3"
+ self.by-version."escape-html"."1.0.1"
+ self.by-version."etag"."1.4.0"
+ self.by-version."fresh"."0.2.4"
+ self.by-version."mime"."1.2.11"
+ self.by-version."ms"."0.6.2"
+ self.by-version."on-finished"."2.1.0"
+ self.by-version."range-parser"."1.0.2"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "send" ];
+ };
+ by-spec."serve-static"."~1.6.3" =
+ self.by-version."serve-static"."1.6.3";
+ by-version."serve-static"."1.6.3" = lib.makeOverridable self.buildNodePackage {
+ name = "node-serve-static-1.6.3";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/serve-static/-/serve-static-1.6.3.tgz";
+ name = "serve-static-1.6.3.tgz";
+ sha1 = "b214235d4d4516db050ea9f7b429b46212e79132";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."serve-static" or []);
+ deps = [
+ self.by-version."escape-html"."1.0.1"
+ self.by-version."parseurl"."1.3.0"
+ self.by-version."send"."0.9.3"
+ self.by-version."utils-merge"."1.0.0"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "serve-static" ];
+ };
by-spec."sntp"."0.2.x" =
self.by-version."sntp"."0.2.4";
by-version."sntp"."0.2.4" = lib.makeOverridable self.buildNodePackage {
@@ -584,7 +1391,7 @@
(self.nativeDeps."tar" or []);
deps = [
self.by-version."block-stream"."0.0.7"
- self.by-version."fstream"."0.1.29"
+ self.by-version."fstream"."0.1.31"
self.by-version."inherits"."2.0.1"
];
peerDependencies = [
@@ -592,6 +1399,25 @@
passthru.names = [ "tar" ];
};
"tar" = self.by-version."tar"."0.1.20";
+ by-spec."tinycolor"."0.x" =
+ self.by-version."tinycolor"."0.0.1";
+ by-version."tinycolor"."0.0.1" = lib.makeOverridable self.buildNodePackage {
+ name = "node-tinycolor-0.0.1";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz";
+ name = "tinycolor-0.0.1.tgz";
+ sha1 = "320b5a52d83abb5978d81a3e887d4aefb15a6164";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."tinycolor" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "tinycolor" ];
+ };
by-spec."tough-cookie".">=0.12.0" =
self.by-version."tough-cookie"."0.12.1";
by-version."tough-cookie"."0.12.1" = lib.makeOverridable self.buildNodePackage {
@@ -606,7 +1432,7 @@
buildInputs =
(self.nativeDeps."tough-cookie" or []);
deps = [
- self.by-version."punycode"."1.3.0"
+ self.by-version."punycode"."1.3.1"
];
peerDependencies = [
];
@@ -631,4 +1457,87 @@
];
passthru.names = [ "tunnel-agent" ];
};
+ by-spec."type-is"."~1.5.1" =
+ self.by-version."type-is"."1.5.2";
+ by-version."type-is"."1.5.2" = lib.makeOverridable self.buildNodePackage {
+ name = "node-type-is-1.5.2";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/type-is/-/type-is-1.5.2.tgz";
+ name = "type-is-1.5.2.tgz";
+ sha1 = "8291bbe845a904acfaffd05a41fdeb234bfa9e5f";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."type-is" or []);
+ deps = [
+ self.by-version."media-typer"."0.3.0"
+ self.by-version."mime-types"."2.0.2"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "type-is" ];
+ };
+ by-spec."utils-merge"."1.0.0" =
+ self.by-version."utils-merge"."1.0.0";
+ by-version."utils-merge"."1.0.0" = lib.makeOverridable self.buildNodePackage {
+ name = "node-utils-merge-1.0.0";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz";
+ name = "utils-merge-1.0.0.tgz";
+ sha1 = "0294fb922bb9375153541c4f7096231f287c8af8";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."utils-merge" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "utils-merge" ];
+ };
+ by-spec."vary"."~1.0.0" =
+ self.by-version."vary"."1.0.0";
+ by-version."vary"."1.0.0" = lib.makeOverridable self.buildNodePackage {
+ name = "node-vary-1.0.0";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/vary/-/vary-1.0.0.tgz";
+ name = "vary-1.0.0.tgz";
+ sha1 = "c5e76cec20d3820d8f2a96e7bee38731c34da1e7";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."vary" or []);
+ deps = [
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "vary" ];
+ };
+ by-spec."ws"."~0.4.32" =
+ self.by-version."ws"."0.4.32";
+ by-version."ws"."0.4.32" = lib.makeOverridable self.buildNodePackage {
+ name = "ws-0.4.32";
+ src = [
+ (fetchurl {
+ url = "http://registry.npmjs.org/ws/-/ws-0.4.32.tgz";
+ name = "ws-0.4.32.tgz";
+ sha1 = "787a6154414f3c99ed83c5772153b20feb0cec32";
+ })
+ ];
+ buildInputs =
+ (self.nativeDeps."ws" or []);
+ deps = [
+ self.by-version."commander"."2.1.0"
+ self.by-version."nan"."1.0.0"
+ self.by-version."tinycolor"."0.0.1"
+ self.by-version."options"."0.0.6"
+ ];
+ peerDependencies = [
+ ];
+ passthru.names = [ "ws" ];
+ };
+ "ws" = self.by-version."ws"."0.4.32";
}
diff --git a/pkgs/applications/editors/zile/default.nix b/pkgs/applications/editors/zile/default.nix
index 32d30cd4745..48839246600 100644
--- a/pkgs/applications/editors/zile/default.nix
+++ b/pkgs/applications/editors/zile/default.nix
@@ -1,14 +1,14 @@
-{ fetchurl, stdenv, ncurses, boehmgc, perl, help2man }:
+{ fetchurl, stdenv, pkgconfig, ncurses, boehmgc, perl, help2man }:
stdenv.mkDerivation rec {
- name = "zile-2.4.9";
+ name = "zile-2.4.11";
src = fetchurl {
url = "mirror://gnu/zile/${name}.tar.gz";
- sha256 = "0j801c28ypm924rw3lqyb6khxyslg6ycrv16wmmwcam0mk3mj6f7";
+ sha256 = "1k593y1xzvlj52q0gyhcx2lllws4sg84b8r9pcginjb1vjypplhz";
};
- buildInputs = [ ncurses boehmgc ];
+ buildInputs = [ pkgconfig ncurses boehmgc ];
nativeBuildInputs = [ help2man perl ];
# `help2man' wants to run Zile, which fails when cross-compiling.
@@ -21,7 +21,7 @@ stdenv.mkDerivation rec {
# XXX: Work around cross-compilation-unfriendly `gl_FUNC_FSTATAT' macro.
preConfigure = "export gl_cv_func_fstatat_zero_flag=yes";
- meta = {
+ meta = with stdenv.lib; {
description = "Lightweight Emacs clone";
longDescription = ''
@@ -45,8 +45,10 @@ stdenv.mkDerivation rec {
homepage = http://www.gnu.org/software/zile/;
- license = stdenv.lib.licenses.gpl3Plus;
+ license = licenses.gpl3Plus;
- maintainers = [ ];
+ maintainers = with maintainers; [ pSub ];
+
+ platforms = platforms.linux;
};
}
diff --git a/pkgs/applications/gis/qgis/default.nix b/pkgs/applications/gis/qgis/default.nix
new file mode 100644
index 00000000000..8e36ec9b168
--- /dev/null
+++ b/pkgs/applications/gis/qgis/default.nix
@@ -0,0 +1,39 @@
+{ stdenv, fetchurl, gdal, cmake, qt4, flex, bison, proj, geos, x11, sqlite, gsl,
+ pyqt4, qwt, fcgi, pythonPackages, libspatialindex, libspatialite, qscintilla, postgresql, makeWrapper }:
+
+stdenv.mkDerivation rec {
+ name = "qgis-2.6.1";
+
+ buildInputs = [ gdal qt4 flex bison proj geos x11 sqlite gsl pyqt4 qwt qscintilla
+ fcgi libspatialindex libspatialite postgresql ] ++
+ (with pythonPackages; [ numpy psycopg2 ]);
+
+ nativeBuildInputs = [ cmake makeWrapper ];
+
+ # fatal error: ui_qgsdelimitedtextsourceselectbase.h: No such file or directory
+ #enableParallelBuilding = true;
+
+ # To handle the lack of 'local' RPATH; required, as they call one of
+ # their built binaries requiring their libs, in the build process.
+ preBuild = ''
+ export LD_LIBRARY_PATH=`pwd`/output/lib:$LD_LIBRARY_PATH
+ '';
+
+ src = fetchurl {
+ url = "http://qgis.org/downloads/${name}.tar.bz2";
+ sha256 = "1avw9mnhrcxsdalqr2yhyif1cacl4dsgcpfc31axkv7vj401djnl";
+ };
+
+ postInstall = ''
+ wrapProgram $out/bin/qgis \
+ --prefix PYTHONPATH : $PYTHONPATH
+ '';
+
+ meta = {
+ description = "User friendly Open Source Geographic Information System";
+ homepage = http://www.qgis.org;
+ license = stdenv.lib.licenses.gpl2Plus;
+ platforms = with stdenv.lib.platforms; linux;
+ maintainers = with stdenv.lib.maintainers; [viric];
+ };
+}
diff --git a/pkgs/applications/gis/saga/default.nix b/pkgs/applications/gis/saga/default.nix
new file mode 100644
index 00000000000..bb31b24bf5e
--- /dev/null
+++ b/pkgs/applications/gis/saga/default.nix
@@ -0,0 +1,23 @@
+{ stdenv, fetchurl, gdal, wxGTK30, proj, libiodbc, lzma, jasper,
+ libharu, opencv, vigra, postgresql }:
+
+stdenv.mkDerivation rec {
+ name = "saga-2.1.4";
+
+ buildInputs = [ gdal wxGTK30 proj libharu opencv vigra postgresql libiodbc lzma jasper ];
+
+ enableParallelBuilding = true;
+
+ src = fetchurl {
+ url = "http://sourceforge.net/projects/saga-gis/files/SAGA%20-%202.1/SAGA%202.1.4/saga_2.1.4.tar.gz";
+ sha256 = "694e4102f592f512c635328c40fdeff33493f74698d9466bb654baf3247e7b76";
+ };
+
+ meta = {
+ description = "System for Automated Geoscientific Analyses";
+ homepage = http://www.saga-gis.org;
+ license = stdenv.lib.licenses.gpl2Plus;
+ maintainers = [ stdenv.lib.maintainers.michelk ];
+ platforms = ["x86_64-linux" ];
+ };
+}
diff --git a/pkgs/applications/graphics/ImageMagick/default.nix b/pkgs/applications/graphics/ImageMagick/default.nix
index 64b1f5b3b2c..7ae24b38c01 100644
--- a/pkgs/applications/graphics/ImageMagick/default.nix
+++ b/pkgs/applications/graphics/ImageMagick/default.nix
@@ -1,54 +1,95 @@
-{ stdenv
-, fetchurl
-, pkgconfig
-, bzip2
-, fontconfig
-, freetype
-, ghostscript ? null
-, libjpeg
-, libpng
-, libtiff
-, libxml2
-, zlib
-, libtool
-, jasper
-, libX11
-, tetex ? null
-, librsvg ? null
+{ stdenv, fetchurl, pkgconfig, libtool
+, libcl ? null, perl ? null, jemalloc ? null, bzip2 ? null, zlib ? null
+, libX11 ? null, libXext ? null, libXt ? null, dejavu_fonts ? null, fftw ? null
+, libfpx ? null, djvulibre ? null, fontconfig ? null, freetype ? null
+, ghostscript ? null, graphviz ? null, jbigkit ? null, libjpeg ? null
+, lcms2 ? null, openjpeg ? null, liblqr1 ? null, xz ? null, openexr ? null
+, pango ? null, libpng ? null, librsvg ? null, libtiff ? null, libwebp ? null
+, libxml2 ? null
}:
let
- version = "6.8.9-0";
+
+ version = "6.9.1-0";
+
+ arch =
+ if stdenv.system == "i686-linux" then "i686"
+ else if stdenv.system == "x86_64-linux" || stdenv.system == "x86_64-darwin" then "x86-64"
+ else throw "ImageMagick is not supported on this platform.";
+
+ mkFlag = trueStr: falseStr: cond: val: "--${if cond then trueStr else falseStr}-${val}";
+ mkWith = mkFlag "with" "without";
+ mkEnable = mkFlag "enable" "disable";
+
+ hasX11 = libX11 != null && libXext != null && libXt != null;
+
in
+
+with stdenv.lib;
stdenv.mkDerivation rec {
- name = "ImageMagick-${version}";
+ name = "imagemagick-${version}";
src = fetchurl {
- url = "mirror://imagemagick/${name}.tar.xz";
- sha256 = "1lapn2798fkc2wn81slpms5p21kq4dsyg45khsk7n8p69cvrmw2b";
+ url = "mirror://imagemagick/releases/ImageMagick-${version}.tar.xz";
+ sha256 = "03lvj6rxv16xk0dpsbzvm2gq5bggkwff9wqbpkq0znihzijpax1j";
};
enableParallelBuilding = true;
- preConfigure = if tetex != null then
- ''
- export DVIDecodeDelegate=${tetex}/bin/dvips
- '' else "";
+ configureFlags = [
+ (mkEnable (libcl != null) "opencl")
+ (mkWith true "modules")
+ (mkWith true "gcc-arch=${arch}")
+ #(mkEnable true "hdri") This breaks some dependencies
+ (mkWith (perl != null) "perl")
+ (mkWith (jemalloc != null) "jemalloc")
+ (mkWith true "frozenpaths")
+ (mkWith (bzip2 != null) "bzlib")
+ (mkWith hasX11 "x")
+ (mkWith (zlib != null) "zlib")
+ (mkWith false "dps")
+ (mkWith (fftw != null) "fftw")
+ (mkWith (libfpx != null) "fpx")
+ (mkWith (djvulibre != null) "djvu")
+ (mkWith (fontconfig != null) "fontconfig")
+ (mkWith (freetype != null) "freetype")
+ (mkWith (ghostscript != null) "gslib")
+ (mkWith (graphviz != null) "gvc")
+ (mkWith (jbigkit != null) "jbig")
+ (mkWith (libjpeg != null) "jpeg")
+ (mkWith (lcms2 != null) "lcms2")
+ (mkWith false "lcms")
+ (mkWith (openjpeg != null) "openjp2")
+ (mkWith (liblqr1 != null) "lqr")
+ (mkWith (xz != null) "lzma")
+ (mkWith (openexr != null) "openexr")
+ (mkWith (pango != null) "pango")
+ (mkWith (libpng != null) "png")
+ (mkWith (librsvg != null) "rsvg")
+ (mkWith (libtiff != null) "tiff")
+ (mkWith (libwebp != null) "webp")
+ (mkWith (libxml2 != null) "xml")
+ ] ++ optional (dejavu_fonts != null) "--with-dejavu-font-dir=${dejavu_fonts}/share/fonts/truetype/"
+ ++ optional (ghostscript != null) "--with-gs-font-dir=${ghostscript}/share/ghostscript/fonts/";
- configureFlags = "" + stdenv.lib.optionalString (stdenv.system != "x86_64-darwin") ''
- --with-gs-font-dir=${ghostscript}/share/ghostscript/fonts
- --with-gslib
- '' + ''
- --with-frozenpaths
- ${if librsvg != null then "--with-rsvg" else ""}
- '';
+ buildInputs = [
+ pkgconfig libtool libcl perl jemalloc bzip2 zlib libX11 libXext libXt fftw
+ libfpx djvulibre fontconfig freetype ghostscript graphviz jbigkit libjpeg
+ lcms2 openjpeg liblqr1 xz openexr pango libpng librsvg libtiff libwebp
+ libxml2
+ ];
- propagatedBuildInputs =
- [ bzip2 fontconfig freetype libjpeg libpng libtiff libxml2 zlib librsvg
- libtool jasper libX11
- ] ++ stdenv.lib.optional (stdenv.system != "x86_64-darwin") ghostscript;
-
- buildInputs = [ tetex pkgconfig ];
+ propagatedBuildInputs = []
+ ++ (stdenv.lib.optional (lcms2 != null) lcms2)
+ ++ (stdenv.lib.optional (liblqr1 != null) liblqr1)
+ ++ (stdenv.lib.optional (fftw != null) fftw)
+ ++ (stdenv.lib.optional (libtool != null) libtool)
+ ++ (stdenv.lib.optional (jemalloc != null) jemalloc)
+ ++ (stdenv.lib.optional (libXext != null) libXext)
+ ++ (stdenv.lib.optional (libX11 != null) libX11)
+ ++ (stdenv.lib.optional (libXt != null) libXt)
+ ++ (stdenv.lib.optional (bzip2 != null) bzip2)
+ ;
postInstall = ''(cd "$out/include" && ln -s ImageMagick* ImageMagick)'';
@@ -56,6 +97,6 @@ stdenv.mkDerivation rec {
homepage = http://www.imagemagick.org/;
description = "A software suite to create, edit, compose, or convert bitmap images";
platforms = platforms.linux ++ [ "x86_64-darwin" ];
- maintainers = with maintainers; [ the-kenny ];
+ maintainers = with maintainers; [ the-kenny wkennington ];
};
}
diff --git a/pkgs/applications/graphics/PythonMagick/default.nix b/pkgs/applications/graphics/PythonMagick/default.nix
index 3e01dc7b2db..17bf7d54670 100644
--- a/pkgs/applications/graphics/PythonMagick/default.nix
+++ b/pkgs/applications/graphics/PythonMagick/default.nix
@@ -1,11 +1,17 @@
{stdenv, fetchurl, python, boost, pkgconfig, imagemagick}:
-stdenv.mkDerivation {
- name = "PythonMagick-0.7";
+let
+
+ version = "0.9.11";
+
+in
+
+stdenv.mkDerivation rec {
+ name = "pythonmagick-${version}";
src = fetchurl {
- url = http://www.imagemagick.org/download/python/PythonMagick-0.7.tar.gz;
- sha256 = "1553kyzdcysii2qhbpbgs0icmfpm6s2lp3zchgs73cxfnfym8lz1";
+ url = "http://www.imagemagick.org/download/python/releases/PythonMagick-${version}.tar.gz";
+ sha256 = "01z01mlqkk0lvrh2jsmf84qjw29sq4rpj0653x7nqy7mrszwwp2v";
};
buildInputs = [python boost pkgconfig imagemagick];
diff --git a/pkgs/applications/graphics/apitrace/default.nix b/pkgs/applications/graphics/apitrace/default.nix
new file mode 100644
index 00000000000..c2f963f001b
--- /dev/null
+++ b/pkgs/applications/graphics/apitrace/default.nix
@@ -0,0 +1,24 @@
+{ stdenv, fetchgit, cmake, python, libX11, qt4 }:
+
+stdenv.mkDerivation {
+ name = "apitrace-09519af205";
+
+ src = fetchgit {
+ url = git://github.com/apitrace/apitrace.git;
+ rev = "09519af2056879ce0ea59f7085ac4b282c7d01d0";
+ sha256 = "1ka34fhl85k90r7kvp89awlqb6prkbqx0kg1whb3535rnvficxdv";
+ };
+
+ buildInputs = [ cmake python libX11 qt4 ];
+
+ buildPhase = ''
+ cmake
+ make
+ '';
+
+ meta = with stdenv.lib; {
+ homepage = https://apitrace.github.io;
+ description = "A set of tools to trace OpenGL, OpenGL ES, Direct3D, and DirectDraw APIs";
+ platforms = platforms.linux;
+ };
+}
diff --git a/pkgs/applications/graphics/cinepaint/default.nix b/pkgs/applications/graphics/cinepaint/default.nix
index 41a4b102a6f..f1ca27eed80 100644
--- a/pkgs/applications/graphics/cinepaint/default.nix
+++ b/pkgs/applications/graphics/cinepaint/default.nix
@@ -28,7 +28,7 @@ stdenv.mkDerivation rec {
meta = {
homepage = http://www.cinepaint.org/;
- license = "free";
+ license = stdenv.lib.licenses.free;
description = "Image editor which supports images over 8bpp and ICC profiles";
maintainers = with stdenv.lib.maintainers; [viric];
platforms = stdenv.lib.platforms.linux;
diff --git a/pkgs/applications/graphics/darktable/default.nix b/pkgs/applications/graphics/darktable/default.nix
index c4e2a7534af..8aefbb9429c 100644
--- a/pkgs/applications/graphics/darktable/default.nix
+++ b/pkgs/applications/graphics/darktable/default.nix
@@ -9,12 +9,12 @@
assert stdenv ? glibc;
stdenv.mkDerivation rec {
- version = "1.4.2";
+ version = "1.6.3";
name = "darktable-${version}";
src = fetchurl {
- url = "mirror://sourceforge/darktable/darktable/1.2/darktable-${version}.tar.xz";
- sha256 = "02875rnabw5m9aqfls59901889iyxkmm4xk445fvh1v06dp1lcf1";
+ url = "https://github.com/darktable-org/darktable/releases/download/release-${version}/darktable-${version}.tar.xz";
+ sha256 = "13gj5z9dz1847wlbn2cqpkvr64ds8yrn5hacs5wvbqmh0z9v6aw5";
};
buildInputs =
@@ -46,9 +46,9 @@ stdenv.mkDerivation rec {
meta = with stdenv.lib; {
description = "Virtual lighttable and darkroom for photographers";
- homepage = http://darktable.sourceforge.net;
+ homepage = http://www.darktable.org;
license = licenses.gpl3Plus;
platforms = platforms.linux;
- maintainers = [ maintainers.goibhniu maintainers.rickynils ];
+ maintainers = [ maintainers.goibhniu maintainers.rickynils maintainers.flosse ];
};
}
diff --git a/pkgs/applications/graphics/dia/default.nix b/pkgs/applications/graphics/dia/default.nix
index da683888063..6200048c41d 100644
--- a/pkgs/applications/graphics/dia/default.nix
+++ b/pkgs/applications/graphics/dia/default.nix
@@ -1,14 +1,14 @@
-{stdenv, fetchurl, fetchurlGnome, gtk, pkgconfig, perl, perlXMLParser, libxml2, gettext
+{stdenv, fetchurl, gtk, pkgconfig, perl, perlXMLParser, libxml2, gettext
, python, libxml2Python, docbook5, docbook_xsl, libxslt, intltool, libart_lgpl
, withGNOME ? false, libgnomeui }:
stdenv.mkDerivation rec {
- name = src.pkgname;
+ name = "dia-${minVer}.3";
+ minVer = "0.97";
- src = fetchurlGnome {
- project = "dia";
- major = "0"; minor = "97"; patchlevel = "2"; extension = "xz";
- sha256 = "1qgawm7rrf4wd1yc0fp39ywv8gbz4ry1s16k00dzg5w6p67lfqd7";
+ src = fetchurl {
+ url = "mirror://gnome/sources/dia/${minVer}/${name}.tar.xz";
+ sha256 = "0d3x6w0l6fwd0l8xx06y1h56xf8ss31yzia3a6xr9y28xx44x492";
};
correctPersistence = fetchurl {
@@ -25,7 +25,7 @@ stdenv.mkDerivation rec {
configureFlags = stdenv.lib.optionalString withGNOME "--enable-gnome";
- patches = [ ./glib-top-level-header.patch ];
+ patches = [ ];
# This file should normally require a gtk-update-icon-cache -q /usr/share/icons/hicolor command
# It have no reasons to exist in a redistribuable package
diff --git a/pkgs/applications/graphics/dia/glib-top-level-header.patch b/pkgs/applications/graphics/dia/glib-top-level-header.patch
deleted file mode 100644
index 80460ae9d72..00000000000
--- a/pkgs/applications/graphics/dia/glib-top-level-header.patch
+++ /dev/null
@@ -1,471 +0,0 @@
-diff -Naur dia-0.97.2-orig/app/app_procs.c dia-0.97.2/app/app_procs.c
---- dia-0.97.2-orig/app/app_procs.c 2011-03-20 07:18:13.000000000 -0400
-+++ dia-0.97.2/app/app_procs.c 2012-07-15 10:49:08.192726306 -0400
-@@ -50,7 +50,7 @@
- #include
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "app_procs.h"
-diff -Naur dia-0.97.2-orig/app/dia-win-remote.c dia-0.97.2/app/dia-win-remote.c
---- dia-0.97.2-orig/app/dia-win-remote.c 2010-08-03 11:35:35.000000000 -0400
-+++ dia-0.97.2/app/dia-win-remote.c 2012-07-15 10:49:08.159726316 -0400
-@@ -35,7 +35,7 @@
- #include
- #include
- #include
--#include
-+#include
-
- /**
- * PROTOTYPES:
-diff -Naur dia-0.97.2-orig/app/filedlg.c dia-0.97.2/app/filedlg.c
---- dia-0.97.2-orig/app/filedlg.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/app/filedlg.c 2012-07-15 10:49:08.227726294 -0400
-@@ -28,7 +28,7 @@
- #include
- #endif
- #include
--#include
-+#include
-
- #undef GTK_DISABLE_DEPRECATED /* gtk_file_chooser_dialog_new_with_backend */
- #include
-diff -Naur dia-0.97.2-orig/app/load_save.c dia-0.97.2/app/load_save.c
---- dia-0.97.2-orig/app/load_save.c 2011-09-25 07:55:11.000000000 -0400
-+++ dia-0.97.2/app/load_save.c 2012-07-15 10:49:08.203726303 -0400
-@@ -30,7 +30,7 @@
- #include
-
- #include
--#include /* g_access() and friends */
-+#include /* g_access() and friends */
- #include
-
- #ifndef W_OK
-diff -Naur dia-0.97.2-orig/app/sheets_dialog_callbacks.c dia-0.97.2/app/sheets_dialog_callbacks.c
---- dia-0.97.2-orig/app/sheets_dialog_callbacks.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/app/sheets_dialog_callbacks.c 2012-07-15 10:49:08.201726302 -0400
-@@ -44,7 +44,7 @@
- #endif
- #endif
-
--#include
-+#include
- #include
-
- #undef GTK_DISABLE_DEPRECATED /* GtkOptionMenu */
-diff -Naur dia-0.97.2-orig/ChangeLog.pre-git dia-0.97.2/ChangeLog.pre-git
---- dia-0.97.2-orig/ChangeLog.pre-git 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/ChangeLog.pre-git 2012-07-15 10:49:08.384726247 -0400
-@@ -4137,7 +4137,7 @@
- plug-ins/vdx/vdx-export.c plug-ins/vdx/vdx-import.c
- plug-ins/wmf/wmf.cpp plug-ins/wpg/wpg.c
- plug-ins/xfig/xfig-export.c plug-ins/xfig/xfig-import.c
-- plug-ins/xslt/xslt.c : use to match GLib's filename
-+ plug-ins/xslt/xslt.c : use to match GLib's filename
- encoding to the io functions used, that is: g_open, g_fopen, g_stat,
- g_unlink, g_mkdir, g_rename (, g_access, g_lstat, g_remove, g_freopen,
- g_chdir, g_rmdir). Also replace gzopen() with gzdopen(g_open(), ...)
-@@ -5995,7 +5995,7 @@
- Also special case strings starting with \tex - i.e. dont escape them -
- to keep the use-case of direct tex input.
-
-- * lib/debug.c : #include not just
-+ * lib/debug.c : #include
-
-
- 2006-01-14 Hans Breuer
-@@ -6207,7 +6207,7 @@
- * lib/makefile.msc : build debug.obj
-
- * plug-ins/makefile.msc : building pgf in the right alphabetical order
-- * plug-ins/pgf/render_pgf.c : include
-+ * plug-ins/pgf/render_pgf.c : include
-
- 2005-12-08 Lars Clausen
-
-diff -Naur dia-0.97.2-orig/lib/debug.c dia-0.97.2/lib/debug.c
---- dia-0.97.2-orig/lib/debug.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/lib/debug.c 2012-07-15 10:49:06.813726730 -0400
-@@ -21,7 +21,7 @@
- #include
-
- #include
--#include
-+#include
- #include
-
- #include "debug.h"
-diff -Naur dia-0.97.2-orig/lib/dia_dirs.c dia-0.97.2/lib/dia_dirs.c
---- dia-0.97.2-orig/lib/dia_dirs.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/lib/dia_dirs.c 2012-07-15 10:49:06.740726750 -0400
-@@ -30,7 +30,7 @@
- #include
- #include
- #endif
--#include
-+#include
-
- /** Get the name of a subdirectory of our data directory.
- * This function does not create the subdirectory, just make the correct name.
-diff -Naur dia-0.97.2-orig/lib/dia_xml.c dia-0.97.2/lib/dia_xml.c
---- dia-0.97.2-orig/lib/dia_xml.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/lib/dia_xml.c 2012-07-15 10:49:06.770726743 -0400
-@@ -25,7 +25,7 @@
- #include
-
- #include
--#include
-+#include
-
- #include
- #include
-diff -Naur dia-0.97.2-orig/objects/custom/shape_typeinfo.c dia-0.97.2/objects/custom/shape_typeinfo.c
---- dia-0.97.2-orig/objects/custom/shape_typeinfo.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/objects/custom/shape_typeinfo.c 2012-07-15 10:49:06.639726783 -0400
-@@ -27,8 +27,8 @@
- #include "custom_util.h"
- #include
- #include
--#include
--#include
-+#include
-+#include
- #include
-
- /*
-diff -Naur dia-0.97.2-orig/objects/SISSI/sissi.c dia-0.97.2/objects/SISSI/sissi.c
---- dia-0.97.2-orig/objects/SISSI/sissi.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/objects/SISSI/sissi.c 2012-07-15 10:49:06.570726804 -0400
-@@ -42,7 +42,7 @@
- #include "dia_xml_libxml.h"
-
- #include
--#include
-+#include
-
- #define DEFAULT_WIDTH 1.0
- #define DEFAULT_HEIGHT 1.0
-diff -Naur dia-0.97.2-orig/objects/standard/image.c dia-0.97.2/objects/standard/image.c
---- dia-0.97.2-orig/objects/standard/image.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/objects/standard/image.c 2012-07-15 10:49:06.683726770 -0400
-@@ -25,7 +25,7 @@
- #ifdef HAVE_UNIST_H
- #include
- #endif
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/cairo/diacairo.c dia-0.97.2/plug-ins/cairo/diacairo.c
---- dia-0.97.2-orig/plug-ins/cairo/diacairo.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/plug-ins/cairo/diacairo.c 2012-07-15 10:49:06.433726846 -0400
-@@ -28,7 +28,7 @@
- #include
- #define G_LOG_DOMAIN "DiaCairo"
- #include
--#include
-+#include
-
- /*
- * To me the following looks rather suspicious. Why do we need to compile
-diff -Naur dia-0.97.2-orig/plug-ins/cairo/diacairo-renderer.c dia-0.97.2/plug-ins/cairo/diacairo-renderer.c
---- dia-0.97.2-orig/plug-ins/cairo/diacairo-renderer.c 2011-01-07 06:54:21.000000000 -0500
-+++ dia-0.97.2/plug-ins/cairo/diacairo-renderer.c 2012-07-15 10:49:06.435726846 -0400
-@@ -28,7 +28,7 @@
- #include
- #define G_LOG_DOMAIN "DiaCairo"
- #include
--#include
-+#include
-
- #ifdef HAVE_PANGOCAIRO_H
- #include
-diff -Naur dia-0.97.2-orig/plug-ins/cgm/cgm.c dia-0.97.2/plug-ins/cgm/cgm.c
---- dia-0.97.2-orig/plug-ins/cgm/cgm.c 2009-12-27 11:22:38.000000000 -0500
-+++ dia-0.97.2/plug-ins/cgm/cgm.c 2012-07-15 10:49:06.425726846 -0400
-@@ -31,7 +31,7 @@
- #include
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/drs/dia-render-script.c dia-0.97.2/plug-ins/drs/dia-render-script.c
---- dia-0.97.2-orig/plug-ins/drs/dia-render-script.c 2009-11-07 12:13:53.000000000 -0500
-+++ dia-0.97.2/plug-ins/drs/dia-render-script.c 2012-07-15 10:49:06.427726848 -0400
-@@ -54,7 +54,7 @@
-
- #define G_LOG_DOMAIN "DiaRenderScript"
- #include
--#include
-+#include
-
- #include "intl.h"
- #include "filter.h"
-diff -Naur dia-0.97.2-orig/plug-ins/dxf/dxf-export.c dia-0.97.2/plug-ins/dxf/dxf-export.c
---- dia-0.97.2-orig/plug-ins/dxf/dxf-export.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/dxf/dxf-export.c 2012-07-15 10:49:06.421726850 -0400
-@@ -29,7 +29,7 @@
- #include
- #include
- #include
--#include
-+#include
-
- #include "autocad_pal.h"
-
-diff -Naur dia-0.97.2-orig/plug-ins/dxf/dxf-import.c dia-0.97.2/plug-ins/dxf/dxf-import.c
---- dia-0.97.2-orig/plug-ins/dxf/dxf-import.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/dxf/dxf-import.c 2012-07-15 10:49:06.419726851 -0400
-@@ -30,7 +30,7 @@
- #include
- #include
- #include
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/hpgl/hpgl.c dia-0.97.2/plug-ins/hpgl/hpgl.c
---- dia-0.97.2-orig/plug-ins/hpgl/hpgl.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/hpgl/hpgl.c 2012-07-15 10:49:06.487726830 -0400
-@@ -37,7 +37,7 @@
- #include
-
- #include
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/libart/export_png.c dia-0.97.2/plug-ins/libart/export_png.c
---- dia-0.97.2-orig/plug-ins/libart/export_png.c 2011-07-03 06:56:08.000000000 -0400
-+++ dia-0.97.2/plug-ins/libart/export_png.c 2012-07-15 10:49:06.415726849 -0400
-@@ -29,7 +29,7 @@
- #include
- #include
-
--#include
-+#include
- #include
-
- #include "intl.h"
-diff -Naur dia-0.97.2-orig/plug-ins/metapost/render_metapost.c dia-0.97.2/plug-ins/metapost/render_metapost.c
---- dia-0.97.2-orig/plug-ins/metapost/render_metapost.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/metapost/render_metapost.c 2012-07-15 10:49:06.396726857 -0400
-@@ -43,7 +43,7 @@
- #endif
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "render_metapost.h"
-diff -Naur dia-0.97.2-orig/plug-ins/pgf/render_pgf.c dia-0.97.2/plug-ins/pgf/render_pgf.c
---- dia-0.97.2-orig/plug-ins/pgf/render_pgf.c 2011-01-07 07:11:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/pgf/render_pgf.c 2012-07-15 10:49:06.445726842 -0400
-@@ -61,8 +61,8 @@
- #endif
- #include
-
--#include
--#include
-+#include
-+#include
-
- #include "intl.h"
- #include "render_pgf.h"
-diff -Naur dia-0.97.2-orig/plug-ins/postscript/paginate_psprint.c dia-0.97.2/plug-ins/postscript/paginate_psprint.c
---- dia-0.97.2-orig/plug-ins/postscript/paginate_psprint.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/postscript/paginate_psprint.c 2012-07-15 10:49:06.451726838 -0400
-@@ -31,7 +31,7 @@
- #include
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/postscript/render_eps.c dia-0.97.2/plug-ins/postscript/render_eps.c
---- dia-0.97.2-orig/plug-ins/postscript/render_eps.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/postscript/render_eps.c 2012-07-15 10:49:06.451726838 -0400
-@@ -55,7 +55,7 @@
- #include
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "render_eps.h"
-diff -Naur dia-0.97.2-orig/plug-ins/pstricks/render_pstricks.c dia-0.97.2/plug-ins/pstricks/render_pstricks.c
---- dia-0.97.2-orig/plug-ins/pstricks/render_pstricks.c 2011-01-07 07:11:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/pstricks/render_pstricks.c 2012-07-15 10:49:06.410726853 -0400
-@@ -50,7 +50,7 @@
- #endif
- #include
-
--#include
-+#include
-
- #include "intl.h"
- #include "render_pstricks.h"
-diff -Naur dia-0.97.2-orig/plug-ins/python/pydia-render.c dia-0.97.2/plug-ins/python/pydia-render.c
---- dia-0.97.2-orig/plug-ins/python/pydia-render.c 2009-11-07 09:28:34.000000000 -0500
-+++ dia-0.97.2/plug-ins/python/pydia-render.c 2012-07-15 10:49:06.503726822 -0400
-@@ -21,7 +21,7 @@
-
- #include
- #include
--#include
-+#include
-
- #include
-
-diff -Naur dia-0.97.2-orig/plug-ins/shape/shape-export.c dia-0.97.2/plug-ins/shape/shape-export.c
---- dia-0.97.2-orig/plug-ins/shape/shape-export.c 2009-11-08 06:14:56.000000000 -0500
-+++ dia-0.97.2/plug-ins/shape/shape-export.c 2012-07-15 10:49:06.489726827 -0400
-@@ -40,7 +40,7 @@
- #include
- #endif
-
--#include
-+#include
-
- /* the dots per centimetre to render this diagram at */
- /* this matches the setting `100%' setting in dia. */
-diff -Naur dia-0.97.2-orig/plug-ins/svg/render_svg.c dia-0.97.2/plug-ins/svg/render_svg.c
---- dia-0.97.2-orig/plug-ins/svg/render_svg.c 2011-12-17 11:30:38.000000000 -0500
-+++ dia-0.97.2/plug-ins/svg/render_svg.c 2012-07-15 10:49:06.392726859 -0400
-@@ -30,7 +30,7 @@
- #endif
-
- #include
--#include
-+#include
-
- #include
- #include
-diff -Naur dia-0.97.2-orig/plug-ins/vdx/vdx-export.c dia-0.97.2/plug-ins/vdx/vdx-export.c
---- dia-0.97.2-orig/plug-ins/vdx/vdx-export.c 2009-12-27 11:22:38.000000000 -0500
-+++ dia-0.97.2/plug-ins/vdx/vdx-export.c 2012-07-15 10:55:17.066579728 -0400
-@@ -32,11 +32,12 @@
-
- #include
- #include
-+#include
- #include
- #include
- #include
- #include
--#include
-+#include
-
- #include "intl.h"
- #include "message.h"
-diff -Naur dia-0.97.2-orig/plug-ins/vdx/vdx-import.c dia-0.97.2/plug-ins/vdx/vdx-import.c
---- dia-0.97.2-orig/plug-ins/vdx/vdx-import.c 2009-12-27 11:22:38.000000000 -0500
-+++ dia-0.97.2/plug-ins/vdx/vdx-import.c 2012-07-15 10:49:06.466726836 -0400
-@@ -28,7 +28,7 @@
- #include
- #include
- #include
--#include
-+#include
- #include
- #include
- #include