Merge remote-tracking branch 'origin/master' into systemd-219

This commit is contained in:
Eelco Dolstra 2015-10-01 14:17:46 +02:00
commit b23038dd80
874 changed files with 44453 additions and 5448 deletions

View File

@ -6,7 +6,7 @@ stdenv.mkDerivation {
sources = sourceFilesBySuffices ./. [".xml"];
buildInputs = [ libxml2 libxslt ];
buildInputs = [ pandoc libxml2 libxslt ];
xsltFlags = ''
--param section.autolabel 1
@ -19,7 +19,23 @@ stdenv.mkDerivation {
'';
buildCommand = ''
ln -s $sources/*.xml . # */
{
echo "<chapter xmlns=\"http://docbook.org/ns/docbook\""
echo " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
echo " xml:id=\"users-guide-to-the-haskell-infrastructure\">"
echo ""
echo "<title>User's Guide to the Haskell Infrastructure</title>"
echo ""
pandoc ${./haskell-users-guide.md} -w docbook | \
sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \
-e 's|<sect. id=|<section xml:id=|' \
-e 's|</sect[0-9]>|</section>|'
echo ""
echo "</chapter>"
} >haskell-users-guide.xml
ln -s "$sources/"*.xml .
echo ${nixpkgsVersion} > .version
@ -37,7 +53,7 @@ stdenv.mkDerivation {
cp ${./style.css} $dst/style.css
mkdir -p $dst/images/callouts
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
cp "${docbook5_xsl}/xml/xsl/docbook/images/callouts/"*.gif $dst/images/callouts/
mkdir -p $out/nix-support
echo "doc manual $dst manual.html" >> $out/nix-support/hydra-build-products

View File

@ -127,7 +127,7 @@ in ...</programlisting>
<title>lib.makeOverridable</title>
<para>
The function <varname>lib.makeOverridable</varname> is used make the result
The function <varname>lib.makeOverridable</varname> is used to make the result
of a function easily customizable. This utility only makes sense for functions
that accept an argument set and return an attribute set.
</para>
@ -248,7 +248,7 @@ c = lib.makeOverridable f { a = 1; b = 2; }</programlisting>
targetPkgs = pkgs: (with pkgs;
[ udev
alsaLib
]) ++ (with pkgs.xlibs;
]) ++ (with pkgs.xorg;
[ libX11
libXcursor
libXrandr

698
doc/haskell-users-guide.md Normal file
View File

@ -0,0 +1,698 @@
---
title: User's Guide for Haskell in Nixpkgs
author: Peter Simons
date: 2015-06-01
---
# How to install Haskell packages
Nixpkgs distributes build instructions for all Haskell packages registered on
[Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package
lookups don't seem to discover any of them, except for the default version of ghc, cabal-install, and stack:
$ nix-env -i alex
error: selector alex matches no derivations
$ nix-env -qa ghc
ghc-7.10.2
The Haskell package set is not registered in the top-level namespace because it
is *huge*. If all Haskell packages were visible to these commands, then
name-based search/install operations would be much slower than they are now. We
avoided that by keeping all Haskell-related packages in a separate attribute
set called `haskellPackages`, which the following command will list:
$ nix-env -f "<nixpkgs>" -qaP -A haskellPackages
haskellPackages.a50 a50-0.5
haskellPackages.abacate haskell-abacate-0.0.0.0
haskellPackages.abcBridge haskell-abcBridge-0.12
haskellPackages.afv afv-0.1.1
haskellPackages.alex alex-3.1.4
haskellPackages.Allure Allure-0.4.101.1
haskellPackages.alms alms-0.6.7
[... some 8000 entries omitted ...]
To install any of those packages into your profile, refer to them by their
attribute path (first column):
$ nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ...
The attribute path of any Haskell packages corresponds to the name of that
particular package on Hackage: the package `cabal-install` has the attribute
`haskellPackages.cabal-install`, and so on. (Actually, this convention causes
trouble with packages like `3dmodels` and `4Blocks`, because these names are
invalid identifiers in the Nix language. The issue of how to deal with these
rare corner cases is currently unresolved.)
Haskell packages who's Nix name (second column) begins with a `haskell-` prefix
are packages that provide a library whereas packages without that prefix
provide just executables. Libraries may provide executables too, though: the
package `haskell-pandoc`, for example, installs both a library and an
application. You can install and use Haskell executables just like any other
program in Nixpkgs, but using Haskell libraries for development is a bit
trickier and we'll address that subject in great detail in section [How to
create a development environment].
Attribute paths are deterministic inside of Nixpkgs, but the path necessary to
reach Nixpkgs varies from system to system. We dodged that problem by giving
`nix-env` an explicit `-f "<nixpkgs>"` parameter, but if you call `nix-env`
without that flag, then chances are the invocation fails:
$ nix-env -iA haskellPackages.cabal-install
error: attribute haskellPackages in selection path
haskellPackages.cabal-install not found
On NixOS, for example, Nixpkgs does *not* exist in the top-level namespace by
default. To figure out the proper attribute path, it's easiest to query for the
path of a well-known Nixpkgs package, i.e.:
$ nix-env -qaP coreutils
nixos.coreutils coreutils-8.23
If your system responds like that (most NixOS installations will), then the
attribute path to `haskellPackages` is `nixos.haskellPackages`. Thus, if you
want to use `nix-env` without giving an explicit `-f` flag, then that's the way
to do it:
$ nix-env -qaP -A nixos.haskellPackages
$ nix-env -iA nixos.haskellPackages.cabal-install
Our current default compiler is GHC 7.10.x and the `haskellPackages` set
contains packages built with that particular version. Nixpkgs contains the
latest major release of every GHC since 6.10.4, however, and there is a whole
family of package sets available that defines Hackage packages built with each
of those compilers, too:
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763
The name `haskellPackages` is really just a synonym for
`haskell.packages.ghc7102`, because we prefer that package set internally and
recommend it to our users as their default choice, but ultimately you are free
to compile your Haskell packages with any GHC version you please. The following
command displays the complete list of available compilers:
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler
haskell.compiler.ghc6104 ghc-6.10.4
haskell.compiler.ghc6123 ghc-6.12.3
haskell.compiler.ghc704 ghc-7.0.4
haskell.compiler.ghc722 ghc-7.2.2
haskell.compiler.ghc742 ghc-7.4.2
haskell.compiler.ghc763 ghc-7.6.3
haskell.compiler.ghc784 ghc-7.8.4
haskell.compiler.ghc7102 ghc-7.10.2
haskell.compiler.ghcHEAD ghc-7.11.20150402
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
haskell.compiler.ghcjs ghcjs-0.1.0
haskell.compiler.jhc jhc-0.8.2
haskell.compiler.uhc uhc-1.1.9.0
We have no package sets for `jhc` or `uhc` yet, unfortunately, but for every
version of GHC listed above, there exists a package set based on that compiler.
Also, the attributes `haskell.compiler.ghcXYC` and
`haskell.packages.ghcXYC.ghc` are synonymous for the sake of convenience.
# How to create a development environment
## How to install a compiler
A simple development environment consists of a Haskell compiler and the tool
`cabal-install`, and we saw in section [How to install Haskell packages] how
you can install those programs into your user profile:
$ nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
Instead of the default package set `haskellPackages`, you can also use the more
precise name `haskell.compiler.ghc7102`, which has the advantage that it refers
to the same GHC version regardless of what Nixpkgs considers "default" at any
given time.
Once you've made those tools available in `$PATH`, it's possible to build
Hackage packages the same way people without access to Nix do it all the time:
$ cabal get lens-4.11 && cd lens-4.11
$ cabal install -j --dependencies-only
$ cabal configure
$ cabal build
If you enjoy working with Cabal sandboxes, then that's entirely possible too:
just execute the command
$ cabal sandbox init
before installing the required dependencies.
The `nix-shell` utility makes it easy to switch to a different compiler
version; just enter the Nix shell environment with the command
$ nix-shell -p haskell.compiler.ghc784
to bring GHC 7.8.4 into `$PATH`. Re-running `cabal configure` switches your
build to use that compiler instead. If you're working on a project that doesn't
depend on any additional system libraries outside of GHC, then it's sufficient
even to run the `cabal configure` command inside of the shell:
$ nix-shell -p haskell.compiler.ghc784 --command "cabal configure"
Afterwards, all other commands like `cabal build` work just fine in any shell
environment, because the configure phase recorded the absolute paths to all
required tools like GHC in its build configuration inside of the `dist/`
directory. Please note, however, that `nix-collect-garbage` can break such an
environment because the Nix store paths created by `nix-shell` aren't "alive"
anymore once `nix-shell` has terminated. If you find that your Haskell builds
no longer work after garbage collection, then you'll have to re-run `cabal
configure` inside of a new `nix-shell` environment.
## How to install a compiler with libraries
GHC expects to find all installed libraries inside of its own `lib` directory.
This approach works fine on traditional Unix systems, but it doesn't work for
Nix, because GHC's store path is immutable once it's built. We cannot install
additional libraries into that location. As a consequence, our copies of GHC
don't know any packages except their own core libraries, like `base`,
`containers`, `Cabal`, etc.
We can register additional libraries to GHC, however, using a special build
function called `ghcWithPackages`. That function expects one argument: a
function that maps from an attribute set of Haskell packages to a list of
packages, which determines the libraries known to that particular version of
GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
generates a copy of GHC that has the `mtl` library registered in addition to
its normal core packages:
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
[nix-shell:~]$ ghc-pkg list mtl
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
mtl-2.2.1
This function allows users to define their own development environment by means
of an override. After adding the following snippet to `~/.nixpkgs/config.nix`,
{
packageOverrides = super: let self = super.pkgs; in
{
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
(haskellPackages: with haskellPackages; [
# libraries
arrows async cgi criterion
# tools
cabal-install haskintex
]);
};
}
it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA
myHaskellEnv`. If you'd like to switch that development environment to a
different version of GHC, just replace the `ghc7102` bit in the previous
definition with the appropriate name. Of course, it's also possible to define
any number of these development environments! (You can't install two of them
into the same profile at the same time, though, because that would result in
file conflicts.)
The generated `ghc` program is a wrapper script that re-directs the real
GHC executable to use a new `lib` directory --- one that we specifically
constructed to contain all those packages the user requested:
$ cat $(type -p ghc)
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc
export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.2/bin/ghc-pkg
export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.2/share/doc/ghc/html
export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.2/lib/ghc-7.10.2
exec /nix/store/j50p...-ghc-7.10.2/bin/ghc "-B$NIX_GHC_LIBDIR" "$@"
The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
`ghcWithPackages` constructed specifically for this environment. The last line
of the wrapper script then executes the real `ghc`, but passes the path to the
new `lib` directory using GHC's `-B` flag.
The purpose of those environment variables is to work around an impurity in the
popular [ghc-paths](http://hackage.haskell.org/package/ghc-paths) library. That
library promises to give its users access to GHC's installation paths. Only,
the library can't possible know that path when it's compiled, because the path
GHC considers its own is determined only much later, when the user configures
it through `ghcWithPackages`. So we [patched
ghc-paths](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/ghc-paths-nix.patch)
to return the paths found in those environment variables at run-time rather
than trying to guess them at compile-time.
To make sure that mechanism works properly all the time, we recommend that you
set those variables to meaningful values in your shell environment, too, i.e.
by adding the following code to your `~/.bashrc`:
if type >/dev/null 2>&1 -p ghc; then
eval "$(egrep ^export "$(type -p ghc)")"
fi
If you are certain that you'll use only one GHC environment which is located in
your user profile, then you can use the following code, too, which has the
advantage that it doesn't contain any paths from the Nix store, i.e. those
settings always remain valid even if a `nix-env -u` operation updates the GHC
environment in your profile:
if [ -e ~/.nix-profile/bin/ghc ]; then
export NIX_GHC="$HOME/.nix-profile/bin/ghc"
export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
fi
## How to install a compiler with libraries, hoogle and documentation indexes
If you plan to use your environment for interactive programming, not just
compiling random Haskell code, you might want to replace `ghcWithPackages` in
all the listings above with `ghcWithHoogle`.
This environment generator not only produces an environment with GHC and all
the specified libraries, but also generates a `hoogle` and `haddock` indexes
for all the packages, and provides a wrapper script around `hoogle` binary that
uses all those things. A precise name for this thing would be
"`ghcWithPackagesAndHoogleAndDocumentationIndexes`", which is, regrettably, too
long and scary.
For example, installing the following environment
{
packageOverrides = super: let self = super.pkgs; in
{
myHaskellEnv = self.haskellPackages.ghcWithHoogle
(haskellPackages: with haskellPackages; [
# libraries
arrows async cgi criterion
# tools
cabal-install haskintex
]);
};
}
allows one to browse module documentation index [not too dissimilar to
this](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html)
for all the specified packages and their dependencies by directing a browser of
choice to `~/.nix-profiles/share/doc/hoogle/index.html` (or
`/run/current-system/sw/share/doc/hoogle/index.html` in case you put it in
`environment.systemPackages` in NixOS).
After you've marveled enough at that try adding the following to your
`~/.ghc/ghci.conf`
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
and test it by typing into `ghci`:
:hoogle a -> a
:doc a -> a
Be sure to note the links to `haddock` files in the output. With any modern and
properly configured terminal emulator you can just click those links to
navigate there.
Finally, you can run
hoogle server -p 8080
and navigate to http://localhost:8080/ for your own local
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
possibly other browsers disallow navigation from `http:` to `file:` URIs for
security reasons, which might be quite an inconvenience. See [this
page](http://kb.mozillazine.org/Links_to_local_pages_do_not_work) for
workarounds.
## How to create ad hoc environments for `nix-shell`
The easiest way to create an ad hoc development environment is to run
`nix-shell` with the appropriate GHC environment given on the command-line:
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
For more sophisticated use-cases, however, it's more convenient to save the
desired configuration in a file called `shell.nix` that looks like this:
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
let
inherit (nixpkgs) pkgs;
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
monad-par mtl
]);
in
pkgs.stdenv.mkDerivation {
name = "my-haskell-env-0";
buildInputs = [ ghc ];
shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
}
Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell
environment that has the appropriate compiler in `$PATH`. If you use `--pure`,
then add all other packages that your development environment needs into the
`buildInputs` attribute. If you'd like to switch to a different compiler
version, then pass an appropriate `compiler` argument to the expression, i.e.
`nix-shell --argstr compiler ghc784`.
If you need such an environment because you'd like to compile a Hackage package
outside of Nix --- i.e. because you're hacking on the latest version from Git
---, then the package set provides suitable nix-shell environments for you
already! Every Haskell package has an `env` attribute that provides a shell
environment suitable for compiling that particular package. If you'd like to
hack the `lens` library, for example, then you just have to check out the
source code and enter the appropriate environment:
$ cabal get lens-4.11 && cd lens-4.11
Downloading lens-4.11...
Unpacking to lens-4.11/
$ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
[nix-shell:/tmp/lens-4.11]$
At point, you can run `cabal configure`, `cabal build`, and all the other
development commands. Note that you need `cabal-install` installed in your
`$PATH` already to use it here --- the `nix-shell` environment does not provide
it.
# How to create Nix builds for your own private Haskell packages
If your own Haskell packages have build instructions for Cabal, then you can
convert those automatically into build instructions for Nix using the
`cabal2nix` utility, which you can install into your profile by running
`nix-env -i cabal2nix`.
## How to build a stand-alone project
For example, let's assume that you're working on a private project called
`foo`. To generate a Nix build expression for it, change into the project's
top-level directory and run the command:
$ cabal2nix . >foo.nix
Then write the following snippet into a file called `default.nix`:
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
Finally, store the following code in a file called `shell.nix`:
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
(import ./default.nix { inherit nixpkgs compiler; }).env
At this point, you can run `nix-build` to have Nix compile your project and
install it into a Nix store path. The local directory will contain a symlink
called `result` after `nix-build` returns that points into that location. Of
course, passing the flag `--argstr compiler ghc763` allows switching the build
to any version of GHC currently supported.
Furthermore, you can call `nix-shell` to enter an interactive development
environment in which you can use `cabal configure` and `cabal build` to develop
your code. That environment will automatically contain a proper GHC derivation
with all the required libraries registered as well as all the system-level
libraries your package might need.
If your package does not depend on any system-level libraries, then it's
sufficient to run
$ nix-shell --command "cabal configure"
once to set up your build. `cabal-install` determines the absolute paths to all
resources required for the build and writes them into a config file in the
`dist/` directory. Once that's done, you can run `cabal build` and any other
command for that project even outside of the `nix-shell` environment. This
feature is particularly nice for those of us who like to edit their code with
an IDE, like Emacs' `haskell-mode`, because it's not necessary to start Emacs
inside of nix-shell just to make it find out the necessary settings for
building the project; `cabal-install` has already done that for us.
If you want to do some quick-and-dirty hacking and don't want to bother setting
up a `default.nix` and `shell.nix` file manually, then you can use the
`--shell` flag offered by `cabal2nix` to have it generate a stand-alone
`nix-shell` environment for you. With that feature, running
$ cabal2nix --shell . >shell.nix
$ nix-shell --command "cabal configure"
is usually enough to set up a build environment for any given Haskell package.
You can even use that generated file to run `nix-build`, too:
$ nix-build shell.nix
## How to build projects that depend on each other
If you have multiple private Haskell packages that depend on each other, then
you'll have to register those packages in the Nixpkgs set to make them visible
for the dependency resolution performed by `callPackage`. First of all, change
into each of your projects top-level directories and generate a `default.nix`
file with `cabal2nix`:
$ cd ~/src/foo && cabal2nix . >default.nix
$ cd ~/src/bar && cabal2nix . >default.nix
Then edit your `~/.nixpkgs/config.nix` file to register those builds in the
default Haskell package set:
{
packageOverrides = super: let self = super.pkgs; in
{
haskellPackages = super.haskellPackages.override {
overrides = self: super: {
foo = self.callPackage ../src/foo {};
bar = self.callPackage ../src/bar {};
};
};
};
}
Once that's accomplished, `nix-env -f "<nixpkgs>" -qA haskellPackages` will
show your packages like any other package from Hackage, and you can build them
$ nix-build "<nixpkgs>" -A haskellPackages.foo
or enter an interactive shell environment suitable for building them:
$ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
# Miscellaneous Topics
## How to build with profiling enabled
Every Haskell package set takes a function called `overrides` that you can use
to manipulate the package as much as you please. One useful application of this
feature is to replace the default `mkDerivation` function with one that enables
library profiling for all packages. To accomplish that, add configure the
following snippet in your `~/.nixpkgs/config.nix` file:
{
packageOverrides = super: let self = super.pkgs; in
{
profiledHaskellPackages = self.haskellPackages.override {
overrides = self: super: {
mkDerivation = args: super.mkDerivation (args // {
enableLibraryProfiling = true;
});
};
};
};
}
Then, replace instances of `haskellPackages` in the `cabal2nix`-generated
`default.nix` or `shell.nix` files with `profiledHaskellPackages`.
## How to override package versions in a compiler-specific package set
Nixpkgs provides the latest version of
[`ghc-events`](http://hackage.haskell.org/package/ghc-events), which is 0.4.4.0
at the time of this writing. This is fine for users of GHC 7.10.x, but GHC
7.8.4 cannot compile that binary. Now, one way to solve that problem is to
register an older version of `ghc-events` in the 7.8.x-specific package set.
The first step is to generate Nix build instructions with `cabal2nix`:
$ cabal2nix cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
Then add the override in `~/.nixpkgs/config.nix`:
{
packageOverrides = super: let self = super.pkgs; in
{
haskell = super.haskell // {
packages = super.haskell.packages // {
ghc784 = super.haskell.packages.ghc784.override {
overrides = self: super: {
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
};
};
};
};
};
}
This code is a little crazy, no doubt, but it's necessary because the intuitive
version
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
overrides = self: super: {
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
};
};
doesn't do what we want it to: that code replaces the `haskell` package set in
Nixpkgs with one that contains only one entry,`packages`, which contains only
one entry `ghc784`. This override loses the `haskell.compiler` set, and it
loses the `haskell.packages.ghcXYZ` sets for all compilers but GHC 7.8.4. To
avoid that problem, we have to perform the convoluted little dance from above,
iterating over each step in hierarchy.
Once it's accomplished, however, we can install a variant of `ghc-events`
that's compiled with GHC 7.8.4:
nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events
Unfortunately, it turns out that this build fails again while executing the
test suite! Apparently, the release archive on Hackage is missing some data
files that the test suite requires, so we cannot run it. We accomplish that by
re-generating the Nix expression with the `--no-check` flag:
$ cabal2nix --no-check cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
Now the builds succeeds.
Of course, in the concrete example of `ghc-events` this whole exercise is not
an ideal solution, because `ghc-events` can analyze the output emitted by any
version of GHC later than 6.12 regardless of the compiler version that was used
to build the `ghc-events' executable, so strictly speaking there's no reason to
prefer one built with GHC 7.8.x in the first place. However, for users who
cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an
older version might be useful.
## How to recover from GHC's infamous non-deterministic library ID bug
GHC and distributed build farms don't get along well:
https://ghc.haskell.org/trac/ghc/ticket/4012
When you see an error like this one
package foo-0.7.1.0 is broken due to missing package
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
then you have to download and re-install `foo` and all its dependents from
scratch:
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
| xargs -L 1 nix-store --repair-path --option binary-caches http://hydra.nixos.org
If you're using additional Hydra servers other than `hydra.nixos.org`, then it
might be necessary to purge the local caches that store data from those
machines to disable these binary channels for the duration of the previous
command, i.e. by running:
rm /nix/var/nix/binary-cache-v3.sqlite
rm /nix/var/nix/manifests/*
rm /nix/var/nix/channel-cache/*
## Builds on Darwin fail with `math.h` not found
Users of GHC on Darwin have occasionally reported that builds fail, because the
compiler complains about a missing include file:
fatal error: 'math.h' file not found
The issue has been discussed at length in [ticket
6390](https://github.com/NixOS/nixpkgs/issues/6390), and so far no good
solution has been proposed. As a work-around, users who run into this problem
can configure the environment variables
export NIX_CFLAGS_COMPILE="-idirafter /usr/include"
export NIX_CFLAGS_LINK="-L/usr/lib"
in their `~/.bashrc` file to avoid the compiler error.
## Using Stack together with Nix
-- While building package zlib-0.5.4.2 using:
runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...]
Process exited with code: ExitFailure 1
Logs have been written to: /home/foo/src/stack-ide/.stack-work/logs/zlib-0.5.4.2.log
Configuring zlib-0.5.4.2...
Setup.hs: Missing dependency on a foreign library:
* Missing (or bad) header file: zlib.h
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
If the header file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
When you run the build inside of the nix-shell environment, the system
is configured to find libz.so without any special flags -- the compiler
and linker "just know" how to find it. Consequently, Cabal won't record
any search paths for libz.so in the package description, which means
that the package works fine inside of nix-shell, but once you leave the
shell the shared object can no longer be found. That issue is by no
means specific to Stack: you'll have that problem with any other
Haskell package that's built inside of nix-shell but run outside of that
environment.
I suppose we could try to remedy the issue by wrapping `stack` or
`cabal` with a script that tries to find those kind of implicit search
paths and makes them explicit on the "cabal configure" command line. I
don't think anyone is working on that subject yet, though, because the
problem doesn't seem so bad in practice.
You can remedy that issue in several ways. First of all, run
$ nix-build --no-out-link "<nixpkgs>" -A zlib
/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8
to find out the store path of the system's zlib library. Now, you can
1) add that path (plus a "/lib" suffix) to your $LD_LIBRARY_PATH
environment variable to make sure your system linker finds libz.so
automatically. It's no pretty solution, but it will work.
2) As a variant of (1), you can also install any number of system
libraries into your user's profile (or some other profile) and point
$LD_LIBRARY_PATH to that profile instead, so that you don't have to
list dozens of those store paths all over the place.
3) The solution I prefer is to call stack with an appropriate
--extra-lib-dirs flag like so:
$ stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
Typically, you'll need --extra-include-dirs as well. It's possible
to add those flag to the project's "stack.yaml" or your user's
global "~/.stack/global/stack.yaml" file so that you don't have to
specify them manually every time.
The same thing applies to `cabal configure`, of course, if you're
building with `cabal-install` instead of Stack.
# Other resources
- The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE)
provides an introduction into Haskell NG aimed at beginners. The slides are
available at http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form
ready for cut & paste -- at
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
- Another Youtube video is [Escaping Cabal Hell with Nix](https://www.youtube.com/watch?v=mQd3s57n_2Y),
which discusses the subject of Haskell development with Nix but also provides
a basic introduction to Nix as well, i.e. it's suitable for viewers with
almost no prior Nix experience.
- Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix).
- The *Journey into the Haskell NG infrastructure* series of postings
describe the new Haskell infrastructure in great detail:
- [Part 1](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html)
explains the differences between the old and the new code and gives
instructions how to migrate to the new setup.
- [Part 2](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015608.html)
looks in-depth at how to tweak and configure your setup by means of
overrides.
- [Part 3](http://lists.science.uu.nl/pipermail/nix-dev/2015-April/016912.html)
describes the infrastructure that keeps the Haskell package set in Nixpkgs
up-to-date.

View File

@ -1,913 +0,0 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="users-guide-to-the-haskell-infrastructure">
<title>User's Guide to the Haskell Infrastructure</title>
<section xml:id="how-to-install-haskell-packages">
<title>How to install Haskell packages</title>
<para>
Nixpkgs distributes build instructions for all Haskell packages
registered on
<link xlink:href="http://hackage.haskell.org/">Hackage</link>, but
strangely enough normal Nix package lookups don't seem to discover
any of them:
</para>
<programlisting>
$ nix-env -qa cabal-install
error: selector cabal-install matches no derivations
$ nix-env -i ghc
error: selector ghc matches no derivations
</programlisting>
<para>
The Haskell package set is not registered in the top-level namespace
because it is <emphasis>huge</emphasis>. If all Haskell packages
were visible to these commands, then name-based search/install
operations would be much slower than they are now. We avoided that
by keeping all Haskell-related packages in a separate attribute set
called <literal>haskellPackages</literal>, which the following
command will list:
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A haskellPackages
haskellPackages.a50 a50-0.5
haskellPackages.abacate haskell-abacate-0.0.0.0
haskellPackages.abcBridge haskell-abcBridge-0.12
haskellPackages.afv afv-0.1.1
haskellPackages.alex alex-3.1.4
haskellPackages.Allure Allure-0.4.101.1
haskellPackages.alms alms-0.6.7
[... some 8000 entries omitted ...]
</programlisting>
<para>
To install any of those packages into your profile, refer to them by
their attribute path (first column):
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.Allure ...
</programlisting>
<para>
The attribute path of any Haskell packages corresponds to the name
of that particular package on Hackage: the package
<literal>cabal-install</literal> has the attribute
<literal>haskellPackages.cabal-install</literal>, and so on.
(Actually, this convention causes trouble with packages like
<literal>3dmodels</literal> and <literal>4Blocks</literal>, because
these names are invalid identifiers in the Nix language. The issue
of how to deal with these rare corner cases is currently
unresolved.)
</para>
<para>
Haskell packages who's Nix name (second column) begins with a
<literal>haskell-</literal> prefix are packages that provide a
library whereas packages without that prefix provide just
executables. Libraries may provide executables too, though: the
package <literal>haskell-pandoc</literal>, for example, installs
both a library and an application. You can install and use Haskell
executables just like any other program in Nixpkgs, but using
Haskell libraries for development is a bit trickier and we'll
address that subject in great detail in section
<link linkend="how-to-create-a-development-environment">How to
create a development environment</link>.
</para>
<para>
Attribute paths are deterministic inside of Nixpkgs, but the path
necessary to reach Nixpkgs varies from system to system. We dodged
that problem by giving <literal>nix-env</literal> an explicit
<literal>-f &quot;&lt;nixpkgs&gt;&quot;</literal> parameter, but if
you call <literal>nix-env</literal> without that flag, then chances
are the invocation fails:
</para>
<programlisting>
$ nix-env -iA haskellPackages.cabal-install
error: attribute haskellPackages in selection path
haskellPackages.cabal-install not found
</programlisting>
<para>
On NixOS, for example, Nixpkgs does <emphasis>not</emphasis> exist
in the top-level namespace by default. To figure out the proper
attribute path, it's easiest to query for the path of a well-known
Nixpkgs package, i.e.:
</para>
<programlisting>
$ nix-env -qaP coreutils
nixos.coreutils coreutils-8.23
</programlisting>
<para>
If your system responds like that (most NixOS installations will),
then the attribute path to <literal>haskellPackages</literal> is
<literal>nixos.haskellPackages</literal>. Thus, if you want to
use <literal>nix-env</literal> without giving an explicit
<literal>-f</literal> flag, then that's the way to do it:
</para>
<programlisting>
$ nix-env -qaP -A nixos.haskellPackages
$ nix-env -iA nixos.haskellPackages.cabal-install
</programlisting>
<para>
Our current default compiler is GHC 7.10.x and the
<literal>haskellPackages</literal> set contains packages built with
that particular version. Nixpkgs contains the latest major release
of every GHC since 6.10.4, however, and there is a whole family of
package sets available that defines Hackage packages built with each
of those compilers, too:
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A haskell.packages.ghc6123
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A haskell.packages.ghc763
</programlisting>
<para>
The name <literal>haskellPackages</literal> is really just a synonym
for <literal>haskell.packages.ghc7102</literal>, because we prefer
that package set internally and recommend it to our users as their
default choice, but ultimately you are free to compile your Haskell
packages with any GHC version you please. The following command
displays the complete list of available compilers:
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A haskell.compiler
haskell.compiler.ghc6104 ghc-6.10.4
haskell.compiler.ghc6123 ghc-6.12.3
haskell.compiler.ghc704 ghc-7.0.4
haskell.compiler.ghc722 ghc-7.2.2
haskell.compiler.ghc742 ghc-7.4.2
haskell.compiler.ghc763 ghc-7.6.3
haskell.compiler.ghc784 ghc-7.8.4
haskell.compiler.ghc7102 ghc-7.10.2
haskell.compiler.ghcHEAD ghc-7.11.20150402
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
haskell.compiler.ghcjs ghcjs-0.1.0
haskell.compiler.jhc jhc-0.8.2
haskell.compiler.uhc uhc-1.1.9.0
</programlisting>
<para>
We have no package sets for <literal>jhc</literal> or
<literal>uhc</literal> yet, unfortunately, but for every version of
GHC listed above, there exists a package set based on that compiler.
Also, the attributes <literal>haskell.compiler.ghcXYC</literal> and
<literal>haskell.packages.ghcXYC.ghc</literal> are synonymous for
the sake of convenience.
</para>
</section>
<section xml:id="how-to-create-a-development-environment">
<title>How to create a development environment</title>
<section xml:id="how-to-install-a-compiler">
<title>How to install a compiler</title>
<para>
A simple development environment consists of a Haskell compiler
and the tool <literal>cabal-install</literal>, and we saw in
section <link linkend="how-to-install-haskell-packages">How to
install Haskell packages</link> how you can install those programs
into your user profile:
</para>
<programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.ghc haskellPackages.cabal-install
</programlisting>
<para>
Instead of the default package set
<literal>haskellPackages</literal>, you can also use the more
precise name <literal>haskell.compiler.ghc7102</literal>, which
has the advantage that it refers to the same GHC version
regardless of what Nixpkgs considers &quot;default&quot; at any
given time.
</para>
<para>
Once you've made those tools available in
<literal>$PATH</literal>, it's possible to build Hackage packages
the same way people without access to Nix do it all the time:
</para>
<programlisting>
$ cabal get lens-4.11 &amp;&amp; cd lens-4.11
$ cabal install -j --dependencies-only
$ cabal configure
$ cabal build
</programlisting>
<para>
If you enjoy working with Cabal sandboxes, then that's entirely
possible too: just execute the command
</para>
<programlisting>
$ cabal sandbox init
</programlisting>
<para>
before installing the required dependencies.
</para>
<para>
The <literal>nix-shell</literal> utility makes it easy to switch
to a different compiler version; just enter the Nix shell
environment with the command
</para>
<programlisting>
$ nix-shell -p haskell.compiler.ghc784
</programlisting>
<para>
to bring GHC 7.8.4 into <literal>$PATH</literal>. Re-running
<literal>cabal configure</literal> switches your build to use that
compiler instead. If you're working on a project that doesn't
depend on any additional system libraries outside of GHC, then
it's sufficient even to run the <literal>cabal configure</literal>
command inside of the shell:
</para>
<programlisting>
$ nix-shell -p haskell.compiler.ghc784 --command &quot;cabal configure&quot;
</programlisting>
<para>
Afterwards, all other commands like <literal>cabal build</literal>
work just fine in any shell environment, because the configure
phase recorded the absolute paths to all required tools like GHC
in its build configuration inside of the <literal>dist/</literal>
directory. Please note, however, that
<literal>nix-collect-garbage</literal> can break such an
environment because the Nix store paths created by
<literal>nix-shell</literal> aren't &quot;alive&quot; anymore once
<literal>nix-shell</literal> has terminated. If you find that your
Haskell builds no longer work after garbage collection, then
you'll have to re-run <literal>cabal configure</literal> inside of
a new <literal>nix-shell</literal> environment.
</para>
</section>
<section xml:id="how-to-install-a-compiler-with-libraries">
<title>How to install a compiler with libraries</title>
<para>
GHC expects to find all installed libraries inside of its own
<literal>lib</literal> directory. This approach works fine on
traditional Unix systems, but it doesn't work for Nix, because
GHC's store path is immutable once it's built. We cannot install
additional libraries into that location. As a consequence, our
copies of GHC don't know any packages except their own core
libraries, like <literal>base</literal>,
<literal>containers</literal>, <literal>Cabal</literal>, etc.
</para>
<para>
We can register additional libraries to GHC, however, using a
special build function called <literal>ghcWithPackages</literal>.
That function expects one argument: a function that maps from an
attribute set of Haskell packages to a list of packages, which
determines the libraries known to that particular version of GHC.
For example, the Nix expression
<literal>ghcWithPackages (pkgs: [pkgs.mtl])</literal> generates a
copy of GHC that has the <literal>mtl</literal> library registered
in addition to its normal core packages:
</para>
<programlisting>
$ nix-shell -p &quot;haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])&quot;
[nix-shell:~]$ ghc-pkg list mtl
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
mtl-2.2.1
</programlisting>
<para>
This function allows users to define their own development
environment by means of an override. After adding the following
snippet to <literal>~/.nixpkgs/config.nix</literal>,
</para>
<programlisting>
{
packageOverrides = super: let self = super.pkgs; in
{
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
(haskellPackages: with haskellPackages; [
# libraries
arrows async cgi criterion
# tools
cabal-install haskintex
]);
};
}
</programlisting>
<para>
it's possible to install that compiler with
<literal>nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA myHaskellEnv</literal>.
If you'd like to switch that development environment to a
different version of GHC, just replace the
<literal>ghc7102</literal> bit in the previous definition with the
appropriate name. Of course, it's also possible to define any
number of these development environments! (You can't install two
of them into the same profile at the same time, though, because
that would result in file conflicts.)
</para>
<para>
The generated <literal>ghc</literal> program is a wrapper script
that re-directs the real GHC executable to use a new
<literal>lib</literal> directory --- one that we specifically
constructed to contain all those packages the user requested:
</para>
<programlisting>
$ cat $(type -p ghc)
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc
export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.2/bin/ghc-pkg
export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.2/share/doc/ghc/html
export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.2/lib/ghc-7.10.2
exec /nix/store/j50p...-ghc-7.10.2/bin/ghc &quot;-B$NIX_GHC_LIBDIR&quot; &quot;$@&quot;
</programlisting>
<para>
The variables <literal>$NIX_GHC</literal>,
<literal>$NIX_GHCPKG</literal>, etc. point to the
<emphasis>new</emphasis> store path
<literal>ghcWithPackages</literal> constructed specifically for
this environment. The last line of the wrapper script then
executes the real <literal>ghc</literal>, but passes the path to
the new <literal>lib</literal> directory using GHC's
<literal>-B</literal> flag.
</para>
<para>
The purpose of those environment variables is to work around an
impurity in the popular
<link xlink:href="http://hackage.haskell.org/package/ghc-paths">ghc-paths</link>
library. That library promises to give its users access to GHC's
installation paths. Only, the library can't possible know that
path when it's compiled, because the path GHC considers its own is
determined only much later, when the user configures it through
<literal>ghcWithPackages</literal>. So we
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/ghc-paths-nix.patch">patched
ghc-paths</link> to return the paths found in those environment
variables at run-time rather than trying to guess them at
compile-time.
</para>
<para>
To make sure that mechanism works properly all the time, we
recommend that you set those variables to meaningful values in
your shell environment, too, i.e. by adding the following code to
your <literal>~/.bashrc</literal>:
</para>
<programlisting>
if type &gt;/dev/null 2&gt;&amp;1 -p ghc; then
eval &quot;$(egrep ^export &quot;$(type -p ghc)&quot;)&quot;
fi
</programlisting>
<para>
If you are certain that you'll use only one GHC environment which
is located in your user profile, then you can use the following
code, too, which has the advantage that it doesn't contain any
paths from the Nix store, i.e. those settings always remain valid
even if a <literal>nix-env -u</literal> operation updates the GHC
environment in your profile:
</para>
<programlisting>
if [ -e ~/.nix-profile/bin/ghc ]; then
export NIX_GHC=&quot;$HOME/.nix-profile/bin/ghc&quot;
export NIX_GHCPKG=&quot;$HOME/.nix-profile/bin/ghc-pkg&quot;
export NIX_GHC_DOCDIR=&quot;$HOME/.nix-profile/share/doc/ghc/html&quot;
export NIX_GHC_LIBDIR=&quot;$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)&quot;
fi
</programlisting>
</section>
<section xml:id="how-to-install-a-compiler-with-indexes">
<title>How to install a compiler with libraries, hoogle and documentation indexes</title>
<para>
If you plan to use your environment for interactive programming,
not just compiling random Haskell code, you might want to
replace <literal>ghcWithPackages</literal> in all the listings
above with <literal>ghcWithHoogle</literal>.
</para>
<para>
This environment generator not only produces an environment with
GHC and all the specified libraries, but also generates a
<literal>hoogle</literal> and <literal>haddock</literal> indexes
for all the packages, and provides a wrapper script around
<literal>hoogle</literal> binary that uses all those things. A
precise name for this thing would be
"<literal>ghcWithPackagesAndHoogleAndDocumentationIndexes</literal>",
which is, regrettably, too long and scary.
</para>
<para>
For example, installing the following environment
</para>
<programlisting>
{
packageOverrides = super: let self = super.pkgs; in
{
myHaskellEnv = self.haskellPackages.ghcWithHoogle
(haskellPackages: with haskellPackages; [
# libraries
arrows async cgi criterion
# tools
cabal-install haskintex
]);
};
}
</programlisting>
<para>
allows one to browse module documentation index <link
xlink:href="https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html">not
too dissimilar to this</link> for all the specified packages and
their dependencies by directing a browser of choice to
<literal>~/.nix-profiles/share/doc/hoogle/index.html</literal>
(or
<literal>/run/current-system/sw/share/doc/hoogle/index.html</literal>
in case you put it in
<literal>environment.systemPackages</literal> in NixOS).
</para>
<para>
After you've marveled enough at that try adding the following to
your <literal>~/.ghc/ghci.conf</literal>
</para>
<programlisting>
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
</programlisting>
<para>
and test it by typing into <literal>ghci</literal>:
</para>
<programlisting>
:hoogle a -> a
:doc a -> a
</programlisting>
<para>
Be sure to note the links to <literal>haddock</literal> files in
the output. With any modern and properly configured terminal
emulator you can just click those links to navigate there.
</para>
<para>
Finally, you can run
</para>
<programlisting>
hoogle server -p 8080
</programlisting>
<para>
and navigate to <link xlink:href="http://localhost:8080/"/> for
your own local <link
xlink:href="https://www.haskell.org/hoogle/">Hoogle</link>.
Note, however, that Firefox and possibly other browsers disallow
navigation from <literal>http:</literal> to
<literal>file:</literal> URIs for security reasons, which might
be quite an inconvenience. See <link
xlink:href="http://kb.mozillazine.org/Links_to_local_pages_do_not_work">this
page</link> for workarounds.
</para>
</section>
<section xml:id="how-to-create-ad-hoc-environments-for-nix-shell">
<title>How to create ad hoc environments for
<literal>nix-shell</literal></title>
<para>
The easiest way to create an ad hoc development environment is to
run <literal>nix-shell</literal> with the appropriate GHC
environment given on the command-line:
</para>
<programlisting>
nix-shell -p &quot;haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])&quot;
</programlisting>
<para>
For more sophisticated use-cases, however, it's more convenient to
save the desired configuration in a file called
<literal>shell.nix</literal> that looks like this:
</para>
<programlisting>
{ nixpkgs ? import &lt;nixpkgs&gt; {}, compiler ? &quot;ghc7102&quot; }:
let
inherit (nixpkgs) pkgs;
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
monad-par mtl
]);
in
pkgs.stdenv.mkDerivation {
name = &quot;my-haskell-env-0&quot;;
buildInputs = [ ghc ];
shellHook = &quot;eval $(egrep ^export ${ghc}/bin/ghc)&quot;;
}
</programlisting>
<para>
Now run <literal>nix-shell</literal> --- or even
<literal>nix-shell --pure</literal> --- to enter a shell
environment that has the appropriate compiler in
<literal>$PATH</literal>. If you use <literal>--pure</literal>,
then add all other packages that your development environment
needs into the <literal>buildInputs</literal> attribute. If you'd
like to switch to a different compiler version, then pass an
appropriate <literal>compiler</literal> argument to the
expression, i.e.
<literal>nix-shell --argstr compiler ghc784</literal>.
</para>
<para>
If you need such an environment because you'd like to compile a
Hackage package outside of Nix --- i.e. because you're hacking on
the latest version from Git ---, then the package set provides
suitable nix-shell environments for you already! Every Haskell
package has an <literal>env</literal> attribute that provides a
shell environment suitable for compiling that particular package.
If you'd like to hack the <literal>lens</literal> library, for
example, then you just have to check out the source code and enter
the appropriate environment:
</para>
<programlisting>
$ cabal get lens-4.11 &amp;&amp; cd lens-4.11
Downloading lens-4.11...
Unpacking to lens-4.11/
$ nix-shell &quot;&lt;nixpkgs&gt;&quot; -A haskellPackages.lens.env
[nix-shell:/tmp/lens-4.11]$
</programlisting>
<para>
At point, you can run <literal>cabal configure</literal>,
<literal>cabal build</literal>, and all the other development
commands. Note that you need <literal>cabal-install</literal>
installed in your <literal>$PATH</literal> already to use it here
--- the <literal>nix-shell</literal> environment does not provide
it.
</para>
</section>
</section>
<section xml:id="how-to-create-nix-builds-for-your-own-private-haskell-packages">
<title>How to create Nix builds for your own private Haskell
packages</title>
<para>
If your own Haskell packages have build instructions for Cabal, then
you can convert those automatically into build instructions for Nix
using the <literal>cabal2nix</literal> utility, which you can
install into your profile by running
<literal>nix-env -i cabal2nix</literal>.
</para>
<section xml:id="how-to-build-a-stand-alone-project">
<title>How to build a stand-alone project</title>
<para>
For example, let's assume that you're working on a private project
called <literal>foo</literal>. To generate a Nix build expression
for it, change into the project's top-level directory and run the
command:
</para>
<programlisting>
$ cabal2nix . &gt;foo.nix
</programlisting>
<para>
Then write the following snippet into a file called
<literal>default.nix</literal>:
</para>
<programlisting>
{ nixpkgs ? import &lt;nixpkgs&gt; {}, compiler ? &quot;ghc7102&quot; }:
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
</programlisting>
<para>
Finally, store the following code in a file called
<literal>shell.nix</literal>:
</para>
<programlisting>
{ nixpkgs ? import &lt;nixpkgs&gt; {}, compiler ? &quot;ghc7102&quot; }:
(import ./default.nix { inherit nixpkgs compiler; }).env
</programlisting>
<para>
At this point, you can run <literal>nix-build</literal> to have
Nix compile your project and install it into a Nix store path. The
local directory will contain a symlink called
<literal>result</literal> after <literal>nix-build</literal>
returns that points into that location. Of course, passing the
flag <literal>--argstr compiler ghc763</literal> allows switching
the build to any version of GHC currently supported.
</para>
<para>
Furthermore, you can call <literal>nix-shell</literal> to enter an
interactive development environment in which you can use
<literal>cabal configure</literal> and
<literal>cabal build</literal> to develop your code. That
environment will automatically contain a proper GHC derivation
with all the required libraries registered as well as all the
system-level libraries your package might need.
</para>
<para>
If your package does not depend on any system-level libraries,
then it's sufficient to run
</para>
<programlisting>
$ nix-shell --command &quot;cabal configure&quot;
</programlisting>
<para>
once to set up your build. <literal>cabal-install</literal>
determines the absolute paths to all resources required for the
build and writes them into a config file in the
<literal>dist/</literal> directory. Once that's done, you can run
<literal>cabal build</literal> and any other command for that
project even outside of the <literal>nix-shell</literal>
environment. This feature is particularly nice for those of us who
like to edit their code with an IDE, like Emacs'
<literal>haskell-mode</literal>, because it's not necessary to
start Emacs inside of nix-shell just to make it find out the
necessary settings for building the project;
<literal>cabal-install</literal> has already done that for us.
</para>
<para>
If you want to do some quick-and-dirty hacking and don't want to
bother setting up a <literal>default.nix</literal> and
<literal>shell.nix</literal> file manually, then you can use the
<literal>--shell</literal> flag offered by
<literal>cabal2nix</literal> to have it generate a stand-alone
<literal>nix-shell</literal> environment for you. With that
feature, running
</para>
<programlisting>
$ cabal2nix --shell . &gt;shell.nix
$ nix-shell --command &quot;cabal configure&quot;
</programlisting>
<para>
is usually enough to set up a build environment for any given
Haskell package. You can even use that generated file to run
<literal>nix-build</literal>, too:
</para>
<programlisting>
$ nix-build shell.nix
</programlisting>
</section>
<section xml:id="how-to-build-projects-that-depend-on-each-other">
<title>How to build projects that depend on each other</title>
<para>
If you have multiple private Haskell packages that depend on each
other, then you'll have to register those packages in the Nixpkgs
set to make them visible for the dependency resolution performed
by <literal>callPackage</literal>. First of all, change into each
of your projects top-level directories and generate a
<literal>default.nix</literal> file with
<literal>cabal2nix</literal>:
</para>
<programlisting>
$ cd ~/src/foo &amp;&amp; cabal2nix . &gt;default.nix
$ cd ~/src/bar &amp;&amp; cabal2nix . &gt;default.nix
</programlisting>
<para>
Then edit your <literal>~/.nixpkgs/config.nix</literal> file to
register those builds in the default Haskell package set:
</para>
<programlisting>
{
packageOverrides = super: let self = super.pkgs; in
{
haskellPackages = super.haskellPackages.override {
overrides = self: super: {
foo = self.callPackage ../src/foo {};
bar = self.callPackage ../src/bar {};
};
};
};
}
</programlisting>
<para>
Once that's accomplished,
<literal>nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qA haskellPackages</literal>
will show your packages like any other package from Hackage, and
you can build them
</para>
<programlisting>
$ nix-build &quot;&lt;nixpkgs&gt;&quot; -A haskellPackages.foo
</programlisting>
<para>
or enter an interactive shell environment suitable for building
them:
</para>
<programlisting>
$ nix-shell &quot;&lt;nixpkgs&gt;&quot; -A haskellPackages.bar.env
</programlisting>
</section>
</section>
<section xml:id="miscellaneous-topics">
<title>Miscellaneous Topics</title>
<section xml:id="how-to-build-with-profiling-enabled">
<title>How to build with profiling enabled</title>
<para>
Every Haskell package set takes a function called
<literal>overrides</literal> that you can use to manipulate the
package as much as you please. One useful application of this
feature is to replace the default <literal>mkDerivation</literal>
function with one that enables library profiling for all packages.
To accomplish that, add configure the following snippet in your
<literal>~/.nixpkgs/config.nix</literal> file:
</para>
<programlisting>
{
packageOverrides = super: let self = super.pkgs; in
{
profiledHaskellPackages = self.haskellPackages.override {
overrides = self: super: {
mkDerivation = args: super.mkDerivation (args // {
enableLibraryProfiling = true;
});
};
};
};
}
</programlisting>
<para>
Then, replace instances of <literal>haskellPackages</literal> in the
<literal>cabal2nix</literal>-generated <literal>default.nix</literal>
or <literal>shell.nix</literal> files with
<literal>profiledHaskellPackages</literal>.
</para>
</section>
<section xml:id="how-to-override-package-versions-in-a-compiler-specific-package-set">
<title>How to override package versions in a compiler-specific
package set</title>
<para>
Nixpkgs provides the latest version of
<link xlink:href="http://hackage.haskell.org/package/ghc-events"><literal>ghc-events</literal></link>,
which is 0.4.4.0 at the time of this writing. This is fine for
users of GHC 7.10.x, but GHC 7.8.4 cannot compile that binary.
Now, one way to solve that problem is to register an older version
of <literal>ghc-events</literal> in the 7.8.x-specific package
set. The first step is to generate Nix build instructions with
<literal>cabal2nix</literal>:
</para>
<programlisting>
$ cabal2nix cabal://ghc-events-0.4.3.0 &gt;~/.nixpkgs/ghc-events-0.4.3.0.nix
</programlisting>
<para>
Then add the override in <literal>~/.nixpkgs/config.nix</literal>:
</para>
<programlisting>
{
packageOverrides = super: let self = super.pkgs; in
{
haskell = super.haskell // {
packages = super.haskell.packages // {
ghc784 = super.haskell.packages.ghc784.override {
overrides = self: super: {
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
};
};
};
};
};
}
</programlisting>
<para>
This code is a little crazy, no doubt, but it's necessary because
the intuitive version
</para>
<programlisting>
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
overrides = self: super: {
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
};
};
</programlisting>
<para>
doesn't do what we want it to: that code replaces the
<literal>haskell</literal> package set in Nixpkgs with one that
contains only one entry,<literal>packages</literal>, which
contains only one entry <literal>ghc784</literal>. This override
loses the <literal>haskell.compiler</literal> set, and it loses
the <literal>haskell.packages.ghcXYZ</literal> sets for all
compilers but GHC 7.8.4. To avoid that problem, we have to perform
the convoluted little dance from above, iterating over each step
in hierarchy.
</para>
<para>
Once it's accomplished, however, we can install a variant of
<literal>ghc-events</literal> that's compiled with GHC 7.8.4:
</para>
<programlisting>
nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskell.packages.ghc784.ghc-events
</programlisting>
<para>
Unfortunately, it turns out that this build fails again while
executing the test suite! Apparently, the release archive on
Hackage is missing some data files that the test suite requires,
so we cannot run it. We accomplish that by re-generating the Nix
expression with the <literal>--no-check</literal> flag:
</para>
<programlisting>
$ cabal2nix --no-check cabal://ghc-events-0.4.3.0 &gt;~/.nixpkgs/ghc-events-0.4.3.0.nix
</programlisting>
<para>
Now the builds succeeds.
</para>
<para>
Of course, in the concrete example of
<literal>ghc-events</literal> this whole exercise is not an ideal
solution, because <literal>ghc-events</literal> can analyze the
output emitted by any version of GHC later than 6.12 regardless of
the compiler version that was used to build the `ghc-events'
executable, so strictly speaking there's no reason to prefer one
built with GHC 7.8.x in the first place. However, for users who
cannot use GHC 7.10.x at all for some reason, the approach of
downgrading to an older version might be useful.
</para>
</section>
<section xml:id="how-to-recover-from-ghcs-infamous-non-deterministic-library-id-bug">
<title>How to recover from GHC's infamous non-deterministic library
ID bug</title>
<para>
GHC and distributed build farms don't get along well:
</para>
<programlisting>
https://ghc.haskell.org/trac/ghc/ticket/4012
</programlisting>
<para>
When you see an error like this one
</para>
<programlisting>
package foo-0.7.1.0 is broken due to missing package
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
</programlisting>
<para>
then you have to download and re-install <literal>foo</literal>
and all its dependents from scratch:
</para>
<programlisting>
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
| xargs -L 1 nix-store --repair-path --option binary-caches http://hydra.nixos.org
</programlisting>
<para>
If you're using additional Hydra servers other than
<literal>hydra.nixos.org</literal>, then it might be necessary to
purge the local caches that store data from those machines to
disable these binary channels for the duration of the previous
command, i.e. by running:
</para>
<programlisting>
rm /nix/var/nix/binary-cache-v3.sqlite
rm /nix/var/nix/manifests/*
rm /nix/var/nix/channel-cache/*
</programlisting>
</section>
<section xml:id="builds-on-darwin-fail-with-math.h-not-found">
<title>Builds on Darwin fail with <literal>math.h</literal> not
found</title>
<para>
Users of GHC on Darwin have occasionally reported that builds
fail, because the compiler complains about a missing include file:
</para>
<programlisting>
fatal error: 'math.h' file not found
</programlisting>
<para>
The issue has been discussed at length in
<link xlink:href="https://github.com/NixOS/nixpkgs/issues/6390">ticket
6390</link>, and so far no good solution has been proposed. As a
work-around, users who run into this problem can configure the
environment variables
</para>
<programlisting>
export NIX_CFLAGS_COMPILE=&quot;-idirafter /usr/include&quot;
export NIX_CFLAGS_LINK=&quot;-L/usr/lib&quot;
</programlisting>
<para>
in their <literal>~/.bashrc</literal> file to avoid the compiler
error.
</para>
</section>
</section>
<section xml:id="other-resources">
<title>Other resources</title>
<itemizedlist>
<listitem>
<para>
The Youtube video
<link xlink:href="https://www.youtube.com/watch?v=BsBhi_r-OeE">Nix
Loves Haskell</link> provides an introduction into Haskell NG
aimed at beginners. The slides are available at
http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form
ready for cut &amp; paste -- at
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
</para>
</listitem>
<listitem>
<para>
Another Youtube video is
<link xlink:href="https://www.youtube.com/watch?v=mQd3s57n_2Y">Escaping
Cabal Hell with Nix</link>, which discusses the subject of
Haskell development with Nix but also provides a basic
introduction to Nix as well, i.e. it's suitable for viewers with
almost no prior Nix experience.
</para>
</listitem>
<listitem>
<para>
Oliver Charles wrote a very nice
<link xlink:href="http://wiki.ocharles.org.uk/Nix">Tutorial how to
develop Haskell packages with Nix</link>.
</para>
</listitem>
<listitem>
<para>
The <emphasis>Journey into the Haskell NG
infrastructure</emphasis> series of postings describe the new
Haskell infrastructure in great detail:
</para>
<itemizedlist>
<listitem>
<para>
<link xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html">Part
1</link> explains the differences between the old and the
new code and gives instructions how to migrate to the new
setup.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015608.html">Part
2</link> looks in-depth at how to tweak and configure your
setup by means of overrides.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2015-April/016912.html">Part
3</link> describes the infrastructure that keeps the
Haskell package set in Nixpkgs up-to-date.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</section>
</chapter>

View File

@ -981,6 +981,72 @@ stdenv.mkDerivation {
</programlisting>
</section>
<section xml:id="sec-language-qt"><title>Qt</title>
<para>The information in this section applies to Qt 5.5 and later.</para>
<para>Qt is an application development toolkit for C++. Although it is
not a distinct programming language, there are special considerations
for packaging Qt-based programs and libraries. A small set of tools
and conventions has grown out of these considerations.</para>
<section xml:id="ssec-qt-libraries"><title>Libraries</title>
<para>Packages that provide libraries should be listed in
<varname>qt5LibsFun</varname> so that the library is built with each
Qt version. A set of packages is provided for each version of Qt; for
example, <varname>qt5Libs</varname> always provides libraries built
with the latest version, <varname>qt55Libs</varname> provides
libraries built with Qt 5.5, and so on. To avoid version conflicts, no
top-level attributes are created for these packages.</para>
</section>
<section xml:id="ssec-qt-programs"><title>Programs</title>
<para>Application packages do not need to be built with every Qt
version. To ensure consistency between the package's dependencies,
call the package with <literal>qt5Libs.callPackage</literal> instead
of the usual <literal>callPackage</literal>. An older version may be
selected in case of incompatibility. For example, to build with Qt
5.5, call the package with
<literal>qt55Libs.callPackage</literal>.</para>
<para>Several environment variables must be set at runtime for Qt
applications to function correctly, including:</para>
<itemizedlist>
<listitem><para><envar>QT_PLUGIN_PATH</envar></para></listitem>
<listitem><para><envar>QML_IMPORT_PATH</envar></para></listitem>
<listitem><para><envar>QML2_IMPORT_PATH</envar></para></listitem>
<listitem><para><envar>XDG_DATA_DIRS</envar></para></listitem>
</itemizedlist>
<para>To ensure that these are set correctly, the program must be wrapped by
invoking <literal>wrapQtProgram <replaceable>program</replaceable></literal>
during installation (for example, during
<literal>fixupPhase</literal>). <literal>wrapQtProgram</literal>
accepts the same options as <literal>makeWrapper</literal>.
</para>
</section>
<section xml:id="ssec-qt-kde"><title>KDE</title>
<para>Many of the considerations above also apply to KDE packages,
especially the need to set the correct environment variables at
runtime. To ensure that this is done, invoke <literal>wrapKDEProgram
<replaceable>program</replaceable></literal> during
installation. <literal>wrapKDEProgram</literal> also generates a
<literal>ksycoca</literal> database so that required data and services
can be found. Like its Qt counterpart,
<literal>wrapKDEProgram</literal> accepts the same options as
<literal>makeWrapper</literal>.</para>
</section>
</section>
<!--
<section><title>Haskell</title>

View File

@ -61,7 +61,7 @@ $ nix-env -qa hello --meta --json
"i686-openbsd",
"x86_64-openbsd"
],
"position": "/home/user/dev/nixpkgs/pkgs/applications/misc/hello/ex-2/default.nix:14"
"position": "/home/user/dev/nixpkgs/pkgs/applications/misc/hello/default.nix:14"
},
"name": "hello-2.9",
"system": "x86_64-linux"

View File

@ -56,7 +56,7 @@ $ git add pkgs/development/libraries/libfoo/default.nix</screen>
<listitem>
<para>GNU Hello: <link
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/hello/ex-2/default.nix"><filename>pkgs/applications/misc/hello/ex-2/default.nix</filename></link>.
xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/hello/default.nix"><filename>pkgs/applications/misc/hello/default.nix</filename></link>.
Trivial package, which specifies some <varname>meta</varname>
attributes which is good practice.</para>
</listitem>

View File

@ -1204,7 +1204,7 @@ echo @foo@
</varlistentry>
<varlistentry>
<term>Qt</term>
<term>Qt 4</term>
<listitem><para>Sets the <envar>QTDIR</envar> environment variable
to Qts path.</para></listitem>
</varlistentry>

View File

@ -164,4 +164,23 @@ rec {
drv' = (lib.head outputsList).value;
in lib.deepSeq drv' drv';
/* Make a set of packages with a common scope. All packages called
with the provided `callPackage' will be evaluated with the same
arguments. Any package in the set may depend on any other. The
`override' function allows subsequent modification of the package
set in a consistent way, i.e. all packages in the set will be
called with the overridden packages. The package sets may be
hierarchical: the packages in the set are called with the scope
provided by `newScope' and the set provides a `newScope' attribute
which can form the parent scope for later package sets. */
makeScope = newScope: f:
let self = f self // {
newScope = scope: newScope (self // scope);
callPackage = self.newScope {};
override = g: makeScope newScope (self_:
let super = f self_;
in super // g super self_);
};
in self;
}

View File

@ -155,6 +155,11 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "GNU Free Documentation License v1.2";
};
fdl13 = spdx {
spdxId = "GFDL-1.3";
fullName = "GNU Free Documentation License v1.2";
};
free = {
fullName = "Unspecified free software license";
};

View File

@ -19,6 +19,7 @@
akc = "Anders Claesson <akc@akc.is>";
algorith = "Dries Van Daele <dries_van_daele@telenet.be>";
all = "Nix Committers <nix-commits@lists.science.uu.nl>";
ambrop72 = "Ambroz Bizjak <ambrop7@gmail.com>";
amiddelk = "Arie Middelkoop <amiddelk@gmail.com>";
amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>";
AndersonTorres = "Anderson Torres <torres.anderson.85@gmail.com>";

View File

@ -31,10 +31,8 @@ let
else
fn;
# Convert the list of options into an XML file. The builtin
# unsafeDiscardStringContext is used to prevent the realisation of
# the store paths which are used in options definitions.
optionsXML = builtins.toFile "options.xml" (builtins.unsafeDiscardStringContext (builtins.toXML optionsList'));
# Convert the list of options into an XML file.
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
optionsDocBook = runCommand "options-db.xml" {} ''
optionsXML=${optionsXML}
@ -139,6 +137,8 @@ in rec {
''; # */
meta.description = "The NixOS manual in HTML format";
allowedReferences = ["out"];
};
manualPDF = stdenv.mkDerivation {
@ -146,12 +146,9 @@ in rec {
inherit sources;
buildInputs = [ libxml2 libxslt dblatex tetex ];
buildInputs = [ libxml2 libxslt dblatex dblatex.tex ];
buildCommand = ''
# TeX needs a writable font cache.
export VARTEXFONTS=$TMPDIR/texfonts
${copySources}
dst=$out/share/doc/nixos
@ -162,7 +159,7 @@ in rec {
mkdir -p $out/nix-support
echo "doc-pdf manual $dst/manual.pdf" >> $out/nix-support/hydra-build-products
''; # */
'';
};
# Generate the NixOS manpages.
@ -190,6 +187,8 @@ in rec {
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
./man-pages.xml
'';
allowedReferences = ["out"];
};
}

View File

@ -4,7 +4,7 @@
version="5.0"
xml:id="sec-release-15.09">
<title>Release 15.09 (“Dingo”, 2015/09/??)</title>
<title>Release 15.09 (“Dingo”, 2015/09/30)</title>
<para>In addition to numerous new and upgraded packages, this release
has the following highlights:</para>
@ -12,16 +12,25 @@ has the following highlights:</para>
<itemizedlist>
<listitem>
<para>The Haskell packages infrastructure has been re-designed
from the ground up. NixOS now distributes the latest version of
every single package registered on <link
xlink:href="http://hackage.haskell.org/">Hackage</link>, i.e. well
over 8000 Haskell packages. Further information and usage
instructions for the improved infrastructure are available at
<link
xlink:href="https://nixos.org/wiki/Haskell">https://nixos.org/wiki/Haskell</link>.
Users migrating from an earlier release will also find helpful
information below, in the list of backwards-incompatible changes.</para>
<para>The <link xlink:href="http://haskell.org/">Haskell</link>
packages infrastructure has been re-designed from the ground up
(&quot;Haskell NG&quot;). NixOS now distributes the latest version
of every single package registered on <link
xlink:href="http://hackage.haskell.org/">Hackage</link> -- well in
excess of 8,000 Haskell packages. Detailed instructions on how to
use that infrastructure can be found in the <link
xlink:href="http://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure">User's
Guide to the Haskell Infrastructure</link>. Users migrating from an
earlier release may find helpful information below, in the list of
backwards-incompatible changes. Furthermore, we distribute 51(!)
additional Haskell package sets that provide every single <link
xlink:href="http://www.stackage.org/">LTS Haskell</link> release
since version 0.0 as well as the most recent <link
xlink:href="http://www.stackage.org/">Stackage Nightly</link>
snapshot. The announcement <link
xlink:href="http://lists.science.uu.nl/pipermail/nix-dev/2015-September/018138.html">&quot;Full
Stackage Support in Nixpkgs&quot;</link> gives additional
details.</para>
</listitem>
<listitem>
@ -47,9 +56,105 @@ system.autoUpgrade.enable = true;
3.18.</para>
</listitem>
<listitem>
<para>GNOME has been upgraded to 3.16.
</para>
</listitem>
<listitem>
<para>Xfce has been upgraded to 4.12.
</para>
</listitem>
<listitem>
<para>KDE 5 has been upgraded to KDE Frameworks 5.10,
Plasma 5.3.2 and Applications 15.04.3.
KDE 4 has been updated to kdelibs-4.14.10.
</para>
</listitem>
<listitem>
<para>E19 has been upgraded to 0.16.8.15.
</para>
</listitem>
</itemizedlist>
<para>The following new services were added since the last release:
<itemizedlist>
<listitem><para><literal>services/mail/exim.nix</literal></para></listitem>
<listitem><para><literal>services/misc/apache-kafka.nix</literal></para></listitem>
<listitem><para><literal>services/misc/canto-daemon.nix</literal></para></listitem>
<listitem><para><literal>services/misc/confd.nix</literal></para></listitem>
<listitem><para><literal>services/misc/devmon.nix</literal></para></listitem>
<listitem><para><literal>services/misc/gitit.nix</literal></para></listitem>
<listitem><para><literal>services/misc/ihaskell.nix</literal></para></listitem>
<listitem><para><literal>services/misc/mbpfan.nix</literal></para></listitem>
<listitem><para><literal>services/misc/mediatomb.nix</literal></para></listitem>
<listitem><para><literal>services/misc/mwlib.nix</literal></para></listitem>
<listitem><para><literal>services/misc/parsoid.nix</literal></para></listitem>
<listitem><para><literal>services/misc/plex.nix</literal></para></listitem>
<listitem><para><literal>services/misc/ripple-rest.nix</literal></para></listitem>
<listitem><para><literal>services/misc/ripple-data-api.nix</literal></para></listitem>
<listitem><para><literal>services/misc/subsonic.nix</literal></para></listitem>
<listitem><para><literal>services/misc/sundtek.nix</literal></para></listitem>
<listitem><para><literal>services/monitoring/cadvisor.nix</literal></para></listitem>
<listitem><para><literal>services/monitoring/das_watchdog.nix</literal></para></listitem>
<listitem><para><literal>services/monitoring/grafana.nix</literal></para></listitem>
<listitem><para><literal>services/monitoring/riemann-tools.nix</literal></para></listitem>
<listitem><para><literal>services/monitoring/teamviewer.nix</literal></para></listitem>
<listitem><para><literal>services/network-filesystems/u9fs.nix</literal></para></listitem>
<listitem><para><literal>services/networking/aiccu.nix</literal></para></listitem>
<listitem><para><literal>services/networking/asterisk.nix</literal></para></listitem>
<listitem><para><literal>services/networking/bird.nix</literal></para></listitem>
<listitem><para><literal>services/networking/charybdis.nix</literal></para></listitem>
<listitem><para><literal>services/networking/docker-registry-server.nix</literal></para></listitem>
<listitem><para><literal>services/networking/fan.nix</literal></para></listitem>
<listitem><para><literal>services/networking/firefox/sync-server.nix</literal></para></listitem>
<listitem><para><literal>services/networking/gateone.nix</literal></para></listitem>
<listitem><para><literal>services/networking/heyefi.nix</literal></para></listitem>
<listitem><para><literal>services/networking/i2p.nix</literal></para></listitem>
<listitem><para><literal>services/networking/lambdabot.nix</literal></para></listitem>
<listitem><para><literal>services/networking/mstpd.nix</literal></para></listitem>
<listitem><para><literal>services/networking/nix-serve.nix</literal></para></listitem>
<listitem><para><literal>services/networking/nylon.nix</literal></para></listitem>
<listitem><para><literal>services/networking/racoon.nix</literal></para></listitem>
<listitem><para><literal>services/networking/skydns.nix</literal></para></listitem>
<listitem><para><literal>services/networking/shout.nix</literal></para></listitem>
<listitem><para><literal>services/networking/softether.nix</literal></para></listitem>
<listitem><para><literal>services/networking/sslh.nix</literal></para></listitem>
<listitem><para><literal>services/networking/tinc.nix</literal></para></listitem>
<listitem><para><literal>services/networking/tlsdated.nix</literal></para></listitem>
<listitem><para><literal>services/networking/tox-bootstrapd.nix</literal></para></listitem>
<listitem><para><literal>services/networking/tvheadend.nix</literal></para></listitem>
<listitem><para><literal>services/networking/zerotierone.nix</literal></para></listitem>
<listitem><para><literal>services/scheduling/marathon.nix</literal></para></listitem>
<listitem><para><literal>services/security/fprintd.nix</literal></para></listitem>
<listitem><para><literal>services/security/hologram.nix</literal></para></listitem>
<listitem><para><literal>services/security/munge.nix</literal></para></listitem>
<listitem><para><literal>services/system/cloud-init.nix</literal></para></listitem>
<listitem><para><literal>services/web-servers/shellinabox.nix</literal></para></listitem>
<listitem><para><literal>services/web-servers/uwsgi.nix</literal></para></listitem>
<listitem><para><literal>services/x11/unclutter.nix</literal></para></listitem>
<listitem><para><literal>services/x11/display-managers/sddm.nix</literal></para></listitem>
<listitem><para><literal>system/boot/coredump.nix</literal></para></listitem>
<listitem><para><literal>system/boot/loader/loader.nix</literal></para></listitem>
<listitem><para><literal>system/boot/loader/generic-extlinux-compatible</literal></para></listitem>
<listitem><para><literal>system/boot/networkd.nix</literal></para></listitem>
<listitem><para><literal>system/boot/resolved.nix</literal></para></listitem>
<listitem><para><literal>system/boot/timesyncd.nix</literal></para></listitem>
<listitem><para><literal>tasks/filesystems/exfat.nix</literal></para></listitem>
<listitem><para><literal>tasks/filesystems/ntfs.nix</literal></para></listitem>
<listitem><para><literal>tasks/filesystems/vboxsf.nix</literal></para></listitem>
<listitem><para><literal>virtualisation/virtualbox-host.nix</literal></para></listitem>
<listitem><para><literal>virtualisation/vmware-guest.nix</literal></para></listitem>
<listitem><para><literal>virtualisation/xen-dom0.nix</literal></para></listitem>
</itemizedlist>
</para>
<para>When upgrading from a previous release, please be aware of the
following incompatible changes:
@ -104,56 +209,75 @@ which contains the latest Elm platform.</para></listitem>
<para>Local printers are no longer shared or advertised by
default. This behavior can be changed by enabling
<literal>services.printing.defaultShared</literal> or
<literal>services.printing.browsing</literal> respectively.</para>
<option>services.printing.defaultShared</option> or
<option>services.printing.browsing</option> respectively.</para>
</listitem>
<listitem>
<para>
The VirtualBox host and guest options have been named more
consistently. They can now found in
<literal>virtualisation.virtualbox.host.*</literal> instead of
<literal>services.virtualboxHost.*</literal> and
<literal>virtualisation.virtualbox.guest.*</literal> instead of
<literal>services.virtualboxGuest.*</literal>.
<option>virtualisation.virtualbox.host.*</option> instead of
<option>services.virtualboxHost.*</option> and
<option>virtualisation.virtualbox.guest.*</option> instead of
<option>services.virtualboxGuest.*</option>.
</para>
<para>
Also, there now is support for the <literal>vboxsf</literal> file
system using the <option>fileSystems</option> configuration
attribute. An example of how this can be used in a configuration:
<programlisting>
fileSystems."/shiny" = {
device = "myshinysharedfolder";
fsType = "vboxsf";
};
</programlisting>
</para>
</listitem>
<listitem>
<para>
Haskell packages can no longer be found by name, i.e. the commands
<literal>nix-env -qa cabal-install</literal> and <literal>nix-env -i
ghc</literal> will fail, even though we <emphasis>do</emphasis> ship
both <literal>cabal-install</literal> and <literal>ghc</literal>.
The reason for this inconvenience is the sheer size of the Haskell
package set: name-based lookups such as these would become much
slower than they are today if we'd add the entire Hackage database
into the top level attribute set. Instead, the list of Haskell
packages can be displayed by
&quot;<literal>nix-env -qa</literal>&quot; no longer discovers
Haskell packages by name. The only packages visible in the global
scope are <literal>ghc</literal>, <literal>cabal-install</literal>,
and <literal>stack</literal>, but all other packages are hidden. The
reason for this inconvenience is the sheer size of the Haskell
package set. Name-based lookups are expensive, and most
<literal>nix-env -qa</literal> operations would become much slower
if we'd add the entire Hackage database into the top level attribute
set. Instead, the list of Haskell packages can be displayed by
running:
</para>
<programlisting>
nix-env -f &quot;&lt;nixpkgs&gt;&quot; -qaP -A haskellPackages
</programlisting>
<para>
and packages can be installed with:
Executable programs written in Haskell can be installed with:
</para>
<programlisting>
nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.cabal-install
nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.pandoc
</programlisting>
<para>
Installing Haskell <emphasis>libraries</emphasis> this way, however, is no
longer supported. See the next item for more details.
</para>
</listitem>
<listitem>
<para>
Previous versions of NixOS came with a feature called
<literal>ghc-wrapper</literal>, a small wrapper script that allows
GHC to transparently pick up on libraries installed in the user's
profile. This feature has been deprecated;
<literal>ghc-wrapper</literal> was removed from the distribution.
The proper way to register Haskell libraries with the compiler now
is the <literal>haskellPackages.ghcWithPackages</literal>
function.
<link xlink:href="https://nixos.org/wiki/Haskell">https://nixos.org/wiki/Haskell</link>
provides much information about this subject.
<literal>ghc-wrapper</literal>, a small script that allowed GHC to
transparently pick up on libraries installed in the user's profile. This
feature has been deprecated; <literal>ghc-wrapper</literal> was removed
from the distribution. The proper way to register Haskell libraries with
the compiler now is the <literal>haskellPackages.ghcWithPackages</literal>
function. The <link
xlink:href="http://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure">User's
Guide to the Haskell Infrastructure</link> provides more information about
this subject.
</para>
</listitem>
@ -203,7 +327,7 @@ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.cabal-install
The <literal>locate</literal> service no longer indexes the Nix store
by default, preventing packages with potentially numerous versions from
cluttering the output. Indexing the store can be activated by setting
<literal>services.locate.includeStore = true</literal>.
<option>services.locate.includeStore = true</option>.
</para>
</listitem>
@ -216,6 +340,107 @@ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.cabal-install
</para>
</listitem>
<listitem>
<para>
Python 2.6 has been marked as broken (as it no longer recieves
security updates from upstream).
</para>
</listitem>
<listitem>
<para>
Any use of module arguments such as <varname>pkgs</varname> to access
library functions, or to define <literal>imports</literal> attributes
will now lead to an infinite loop at the time of the evaluation.
</para>
<para>
In case of an infinite loop, use the <command>--show-trace</command>
command line argument and read the line just above the error message.
<screen>
$ nixos-rebuild build --show-trace
while evaluating the module argument `pkgs' in "/etc/nixos/my-module.nix":
infinite recursion encountered
</screen>
</para>
<para>
Any use of <literal>pkgs.lib</literal>, should be replaced by
<varname>lib</varname>, after adding it as argument of the module. The
following module
<programlisting>
{ config, pkgs, ... }:
with pkgs.lib;
{
options = {
foo = mkOption { … };
};
config = mkIf config.foo { … };
}
</programlisting>
should be modified to look like:
<programlisting>
{ config, pkgs, lib, ... }:
with lib;
{
options = {
foo = mkOption { <replaceable>option declaration</replaceable> };
};
config = mkIf config.foo { <replaceable>option definition</replaceable> };
}
</programlisting>
</para>
<para>
When <varname>pkgs</varname> is used to download other projects to
import their modules, and only in such cases, it should be replaced by
<literal>(import &lt;nixpkgs&gt; {})</literal>. The following module
<programlisting>
{ config, pkgs, ... }:
let
myProject = pkgs.fetchurl {
src = <replaceable>url</replaceable>;
sha256 = <replaceable>hash</replaceable>;
};
in
{
imports = [ "${myProject}/module.nix" ];
}
</programlisting>
should be modified to look like:
<programlisting>
{ config, pkgs, ... }:
let
myProject = (import &lt;nixpkgs&gt; {}).fetchurl {
src = <replaceable>url</replaceable>;
sha256 = <replaceable>hash</replaceable>;
};
in
{
imports = [ "${myProject}/module.nix" ];
}
</programlisting>
</para>
</listitem>
</itemizedlist>
</para>
@ -239,10 +464,26 @@ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA haskellPackages.cabal-install
discovered in the Diffie-Hellman key exchange</link> can now
replace OpenSSH's default version with one they generated
themselves using the new
<literal>services.openssh.moduliFile</literal> option.
<option>services.openssh.moduliFile</option> option.
</para>
</listitem>
<listitem> <para>
A newly packaged TeX Live 2015 is provided in <literal>pkgs.texlive</literal>,
split into 6500 nix packages. For basic user documentation see
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/release-15.09/pkgs/tools/typesetting/tex/texlive-new/default.nix#L1"
>the source</link>.
Beware of <link xlink:href="https://github.com/NixOS/nixpkgs/issues/9757"
>an issue</link> when installing a too large package set.
The plan is to deprecate and maybe delete the original TeX packages
until the next release.
</para> </listitem>
<listitem><para>
<option>buildEnv.env</option> on all Python interpreters
is now available for nix-shell interoperability.
</para> </listitem>
</itemizedlist>
</para>

View File

@ -0,0 +1,115 @@
{ pkgs
, lib
, # The NixOS configuration to be installed onto the disk image.
config
, # The size of the disk, in megabytes.
diskSize
, # Whether the disk should be partitioned (with a single partition
# containing the root filesystem) or contain the root filesystem
# directly.
partitioned ? true
, # The root file system type.
fsType ? "ext4"
, # The initial NixOS configuration file to be copied to
# /etc/nixos/configuration.nix.
configFile ? null
, # Shell code executed after the VM has finished.
postVM ? ""
}:
with lib;
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "nixos-disk-image"
{ preVM =
''
mkdir $out
diskImage=$out/nixos.img
${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "${toString diskSize}M"
mv closure xchg/
'';
buildInputs = [ pkgs.utillinux pkgs.perl pkgs.e2fsprogs pkgs.parted ];
exportReferencesGraph =
[ "closure" config.system.build.toplevel ];
inherit postVM;
}
''
${if partitioned then ''
# Create a single / partition.
parted /dev/vda mklabel msdos
parted /dev/vda -- mkpart primary ext2 1M -1s
. /sys/class/block/vda1/uevent
mknod /dev/vda1 b $MAJOR $MINOR
rootDisk=/dev/vda1
'' else ''
rootDisk=/dev/vda
''}
# Create an empty filesystem and mount it.
mkfs.${fsType} -L nixos $rootDisk
${optionalString (fsType == "ext4") ''
tune2fs -c 0 -i 0 $rootDisk
''}
mkdir /mnt
mount $rootDisk /mnt
# The initrd expects these directories to exist.
mkdir /mnt/dev /mnt/proc /mnt/sys
mount -o bind /proc /mnt/proc
mount -o bind /dev /mnt/dev
mount -o 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)..."
set -f
cp -prd $storePaths /mnt/nix/store/
# 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 ""
# Add missing size/hash fields to the database. FIXME:
# exportReferencesGraph should provide these directly.
chroot /mnt ${config.nix.package}/bin/nix-store --verify --check-contents
# Create the system profile to allow nixos-rebuild to work.
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.
mkdir -p /mnt/etc
touch /mnt/etc/NIXOS
# `switch-to-configuration' requires a /bin/sh
mkdir -p /mnt/bin
ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
# Install a configuration.nix.
mkdir -p /mnt/etc/nixos
${optionalString (configFile != null) ''
cp ${configFile} /mnt/etc/nixos/configuration.nix
''}
# Generate the GRUB menu.
ln -s vda /dev/xvda
ln -s vda /dev/sda
chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
umount /mnt/proc /mnt/dev /mnt/sys
umount /mnt
# Do an fsck to make sure resize2fs works.
fsck.${fsType} -f -y $rootDisk
''
)

View File

@ -1,5 +0,0 @@
{ modulesPath, ...}:
{
imports = [ "${modulesPath}/virtualisation/amazon-init.nix" ];
services.journald.rateLimitBurst = 0;
}

View File

@ -1,5 +0,0 @@
{ config, pkgs, ...}:
{
imports = [ ./amazon-base-config.nix ];
ec2.hvm = true;
}

View File

@ -1,34 +0,0 @@
{ config, pkgs, lib, ...}:
let
cloudUtils = pkgs.fetchurl {
url = "https://launchpad.net/cloud-utils/trunk/0.27/+download/cloud-utils-0.27.tar.gz";
sha256 = "16shlmg36lidp614km41y6qk3xccil02f5n3r4wf6d1zr5n4v8vd";
};
growpart = pkgs.stdenv.mkDerivation {
name = "growpart";
src = cloudUtils;
buildPhase = ''
cp bin/growpart $out
sed -i 's|awk|gawk|' $out
sed -i 's|sed|gnused|' $out
'';
dontInstall = true;
dontPatchShebangs = true;
};
in
{
imports = [ ./amazon-base-config.nix ];
ec2.hvm = true;
boot.loader.grub.device = lib.mkOverride 0 "/dev/xvdg";
boot.kernelParams = [ "console=ttyS0" ];
boot.initrd.extraUtilsCommands = ''
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 = ''
[ -e /dev/xvda ] && [ -e /dev/xvda1 ] && TMPDIR=/run sh $(type -P growpart) /dev/xvda 1
'';
}

View File

@ -0,0 +1,27 @@
{ config, lib, pkgs, ... }:
with lib;
{
imports =
[ ../../../modules/installer/cd-dvd/channel.nix
../../../modules/virtualisation/amazon-image.nix
];
system.build.amazonImage = import ../../../lib/make-disk-image.nix {
inherit pkgs lib config;
partitioned = config.ec2.hvm;
diskSize = if config.ec2.hvm then 2048 else 8192;
configFile = pkgs.writeText "configuration.nix"
''
{
imports = [ <nixpkgs/nixos/modules/virtualisation/amazon-image.nix> ];
${optionalString config.ec2.hvm ''
ec2.hvm = true;
''}
}
'';
};
}

View File

@ -0,0 +1,217 @@
#! /bin/sh -e
set -o pipefail
#set -x
stateDir=${TMPDIR:-/tmp}/ec2-image
echo "keeping state in $stateDir"
mkdir -p $stateDir
version=$(nix-instantiate --eval --strict '<nixpkgs>' -A lib.nixpkgsVersion | sed s/'"'//g)
echo "NixOS version is $version"
rm -f ec2-amis.nix
for type in hvm pv; do
link=$stateDir/$type
imageFile=$link/nixos.img
system=x86_64-linux
arch=x86_64
# Build the image.
if ! [ -L $link ]; then
if [ $type = pv ]; then hvmFlag=false; else hvmFlag=true; fi
echo "building image type '$type'..."
nix-build -o $link \
'<nixpkgs/nixos>' \
-A config.system.build.amazonImage \
--arg configuration "{ imports = [ <nixpkgs/nixos/maintainers/scripts/ec2/amazon-image.nix> ]; ec2.hvm = $hvmFlag; }"
fi
for store in ebs s3; do
bucket=nixos-amis
bucketDir="$version-$type-$store"
prevAmi=
prevRegion=
for region in eu-west-1 eu-central-1 us-east-1 us-west-1 us-west-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 sa-east-1; do
name=nixos-$version-$arch-$type-$store
description="NixOS $system $version ($type-$store)"
amiFile=$stateDir/$region.$type.$store.ami-id
if ! [ -e $amiFile ]; then
echo "doing $name in $region..."
if [ -n "$prevAmi" ]; then
ami=$(ec2-copy-image \
--region "$region" \
--source-region "$prevRegion" --source-ami-id "$prevAmi" \
--name "$name" --description "$description" | cut -f 2)
else
if [ $store = s3 ]; then
# Bundle the image.
imageDir=$stateDir/$type-bundled
if ! [ -d $imageDir ]; then
rm -rf $imageDir.tmp
mkdir -p $imageDir.tmp
ec2-bundle-image \
-d $imageDir.tmp \
-i $imageFile --arch $arch \
--user "$AWS_ACCOUNT" -c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
mv $imageDir.tmp $imageDir
fi
# Upload the bundle to S3.
if ! [ -e $imageDir/uploaded ]; then
echo "uploading bundle to S3..."
ec2-upload-bundle \
-m $imageDir/nixos.img.manifest.xml \
-b "$bucket/$bucketDir" \
-a "$EC2_ACCESS_KEY" -s "$EC2_SECRET_KEY" \
--location EU
touch $imageDir/uploaded
fi
extraFlags="$bucket/$bucketDir/nixos.img.manifest.xml"
else
# Convert the image to vhd format so we don't have
# to upload a huge raw image.
vhdFile=$stateDir/$type.vhd
if ! [ -e $vhdFile ]; then
qemu-img convert -O vpc $imageFile $vhdFile.tmp
mv $vhdFile.tmp $vhdFile
fi
taskId=$(cat $stateDir/$region.$type.task-id 2> /dev/null || true)
volId=$(cat $stateDir/$region.$type.vol-id 2> /dev/null || true)
snapId=$(cat $stateDir/$region.$type.snap-id 2> /dev/null || true)
# Import the VHD file.
if [ -z "$snapId" -a -z "$volId" -a -z "$taskId" ]; then
echo "importing $vhdFile..."
taskId=$(ec2-import-volume $vhdFile --no-upload -f vhd \
-o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY" \
--region "$region" -z "${region}a" \
--bucket "$bucket" --prefix "$bucketDir/" \
| tee /dev/stderr \
| sed 's/.*\(import-vol-[0-9a-z]\+\).*/\1/ ; t ; d')
echo -n "$taskId" > $stateDir/$region.$type.task-id
fi
if [ -z "$snapId" -a -z "$volId" ]; then
ec2-resume-import $vhdFile -t "$taskId" --region "$region" \
-o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY"
fi
# Wait for the volume creation to finish.
if [ -z "$snapId" -a -z "$volId" ]; then
echo "waiting for import to finish..."
while true; do
volId=$(ec2-describe-conversion-tasks "$taskId" --region "$region" | sed 's/.*VolumeId.*\(vol-[0-9a-f]\+\).*/\1/ ; t ; d')
if [ -n "$volId" ]; then break; fi
sleep 10
done
echo -n "$volId" > $stateDir/$region.$type.vol-id
fi
# Delete the import task.
if [ -n "$volId" -a -n "$taskId" ]; then
echo "removing import task..."
ec2-delete-disk-image -t "$taskId" --region "$region" -o "$EC2_ACCESS_KEY" -w "$EC2_SECRET_KEY" || true
rm -f $stateDir/$region.$type.task-id
fi
# Create a snapshot.
if [ -z "$snapId" ]; then
echo "creating snapshot..."
snapId=$(ec2-create-snapshot "$volId" --region "$region" | cut -f 2)
echo -n "$snapId" > $stateDir/$region.$type.snap-id
ec2-create-tags "$snapId" -t "Name=$description" --region "$region"
fi
# Wait for the snapshot to finish.
echo "waiting for snapshot to finish..."
while true; do
status=$(ec2-describe-snapshots "$snapId" --region "$region" | head -n1 | cut -f 4)
if [ "$status" = completed ]; then break; fi
sleep 10
done
# Delete the volume.
if [ -n "$volId" ]; then
echo "deleting volume..."
ec2-delete-volume "$volId" --region "$region" || true
rm -f $stateDir/$region.$type.vol-id
fi
extraFlags="-b /dev/sda1=$snapId:20:true:gp2"
if [ $type = pv ]; then
extraFlags+=" --root-device-name=/dev/sda1"
fi
extraFlags+=" -b /dev/sdb=ephemeral0 -b /dev/sdc=ephemeral1 -b /dev/sdd=ephemeral2 -b /dev/sde=ephemeral3"
fi
# Register the AMI.
if [ $type = pv ]; then
kernel=$(ec2-describe-images -o amazon --filter "manifest-location=*pv-grub-hd0_1.04-$arch*" --region "$region" | cut -f 2)
[ -n "$kernel" ]
echo "using PV-GRUB kernel $kernel"
extraFlags+=" --virtualization-type paravirtual --kernel $kernel"
else
extraFlags+=" --virtualization-type hvm"
fi
ami=$(ec2-register \
-n "$name" \
-d "$description" \
--region "$region" \
--architecture "$arch" \
$extraFlags | cut -f 2)
fi
echo -n "$ami" > $amiFile
echo "created AMI $ami of type '$type' in $region..."
else
ami=$(cat $amiFile)
fi
if [ -z "$NO_WAIT" -o -z "$prevAmi" ]; then
echo "waiting for AMI..."
while true; do
status=$(ec2-describe-images "$ami" --region "$region" | head -n1 | cut -f 5)
if [ "$status" = available ]; then break; fi
sleep 10
done
ec2-modify-image-attribute \
--region "$region" "$ami" -l -a all
fi
echo "region = $region, type = $type, store = $store, ami = $ami"
if [ -z "$prevAmi" ]; then
prevAmi="$ami"
prevRegion="$region"
fi
echo " \"15.09\".$region.$type-$store = \"$ami\";" >> ec2-amis.nix
done
done
done

View File

@ -1,216 +0,0 @@
#! /usr/bin/env python
import os
import sys
import time
import argparse
import nixops.util
from nixops import deployment
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
import boto.ec2
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="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"
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 = "lb-nixos";
resources.ec2KeyPairs.keypair.region = "{0}";
machine =
{{ pkgs, ... }}:
{{
deployment.ec2.accessKeyId = "lb-nixos";
deployment.ec2.region = "{0}";
deployment.ec2.blockDeviceMapping."/dev/xvdg".size = pkgs.lib.mkOverride 10 {1};
}};
}}
'''.format(args.region, ebs_size))
f.close()
db = StateFile(get_default_state_file())
try:
depl = db.open_deployment("ebs-creator")
except Exception:
depl = db.create_deployment()
depl.name = "ebs-creator"
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)
m = depl.machines['machine']
# Do the installation.
device="/dev/xvdg"
if args.hvm:
m.run_command('parted -s /dev/xvdg -- mklabel msdos')
m.run_command('parted -s /dev/xvdg -- mkpart primary ext2 1M -1s')
device="/dev/xvdg1"
m.run_command("if mountpoint -q /mnt; then umount /mnt; fi")
m.run_command("mkfs.ext4 -L nixos {0}".format(device))
m.run_command("mkdir -p /mnt")
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 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 '<nixpkgs>'", capture_stdout=True).split(' ')[0].replace('"','').strip()
print >> sys.stderr, "NixOS version is {0}".format(version)
if args.hvm:
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/amazon-base-config.nix")
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")
else:
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix")
m.run_command("nixos-install")
m.run_command("umount /mnt")
if args.hvm:
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)
description = "NixOS {0} (x86_64; EBS root)".format(version)
# Wait for the snapshot to finish.
def check():
status = snapshot.update()
print >> sys.stderr, "snapshot status is {0}".format(status)
return status == '100%'
m.connect()
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
# 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)
m._conn.create_tags([snapshot.id], {'Name': ami_name})
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)
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")
common_args = dict(
name=ami_name,
description=description,
architecture="x86_64",
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)
print >> sys.stderr, "sleeping a bit..."
time.sleep(30)
print >> sys.stderr, "setting image name..."
m._conn.create_tags([ami_id], {'Name': ami_name})
print >> sys.stderr, "making image public..."
image = m._conn.get_all_images(image_ids=[ami_id])[0]
image.set_launch_permissions(user_ids=[], group_names=["all"])
# Do a test deployment to make sure that the AMI works.
f = open("ebs-test.nix", "w")
f.write(
'''
{{
network.description = "NixOS EBS test";
resources.ec2KeyPairs.keypair.accessKeyId = "lb-nixos";
resources.ec2KeyPairs.keypair.region = "{0}";
machine = {{ config, pkgs, resources, ... }}: {{
deployment.targetEnv = "ec2";
deployment.ec2.accessKeyId = "lb-nixos";
deployment.ec2.region = "{0}";
deployment.ec2.instanceType = "{2}";
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
deployment.ec2.securityGroups = [ "public-ssh" ];
deployment.ec2.ami = "{1}";
}};
}}
'''.format(args.region, ami_id, instance_type))
f.close()
test_depl = db.create_deployment()
test_depl.auto_response = "y"
test_depl.name = "ebs-creator-test"
test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]
test_depl.deploy(create_only=True)
test_depl.machines['machine'].run_command("nixos-version")
# Log the AMI ID.
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', 'eu-central-1', 'ap-southeast-1', 'ap-southeast-2', 'ap-northeast-1', 'sa-east-1']:
copy_image = None
if args.region != dest:
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.
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()

View File

@ -1,53 +0,0 @@
#! /bin/sh -e
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/amazon-base-config.nix
version=$(nix-instantiate --eval-only '<nixpkgs/nixos>' -A config.system.nixosVersion | sed s/'"'//g)
echo "NixOS version is $version"
buildAndUploadFor() {
system="$1"
arch="$2"
echo "building $system image..."
nix-build '<nixpkgs/nixos>' \
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
-c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
for region in eu-west-1; do
echo "uploading $system image for $region..."
name=nixos-$version-$arch-s3
bucket="$(echo $name-$region | tr '[A-Z]_' '[a-z]-')"
if [ "$region" = eu-west-1 ]; then s3location=EU;
elif [ "$region" = us-east-1 ]; then s3location=US;
else s3location="$region"
fi
ec2-upload-bundle -b "$bucket" -m /tmp/nixos.img.manifest.xml \
-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.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" -O "$EC2_ACCESS_KEY" -W "$EC2_SECRET_KEY" \
--region "$region" --kernel "$kernel" | cut -f 2)
echo "AMI ID is $ami"
echo " \"14.12\".\"$region\".s3 = \"$ami\";" >> ec2-amis.nix
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
}
buildAndUploadFor x86_64-linux x86_64

View File

@ -1,13 +0,0 @@
{
network.description = "NixOS EBS creator";
machine =
{ config, pkgs, resources, ... }:
{ deployment.targetEnv = "ec2";
deployment.ec2.instanceType = "c3.large";
deployment.ec2.securityGroups = [ "public-ssh" ];
deployment.ec2.ebsBoot = false;
deployment.ec2.keyPair = resources.ec2KeyPairs.keypair.name;
environment.systemPackages = [ pkgs.parted ];
};
}

View File

@ -31,6 +31,7 @@ with lib;
pkgs.xorg.fontbh100dpi
pkgs.xorg.fontmiscmisc
pkgs.xorg.fontcursormisc
pkgs.unifont
];
};

View File

@ -39,6 +39,16 @@ in
'';
};
networking.extraResolvconfConf = lib.mkOption {
type = types.lines;
default = "";
example = "libc=NO";
description = ''
Extra configuration to append to <filename>resolvconf.conf</filename>.
'';
};
networking.proxy = {
default = lib.mkOption {
@ -150,6 +160,7 @@ in
'' + optionalString dnsmasqResolve ''
dnsmasq_conf=/etc/dnsmasq-conf.conf
dnsmasq_resolv=/etc/dnsmasq-resolv.conf
'' + cfg.extraResolvconfConf + ''
'';
} // (optionalAttrs config.services.resolved.enable (

View File

@ -57,8 +57,8 @@ in
type = types.attrsOf (types.listOf types.str);
example = { PATH = [ "/bin" "/sbin" ]; MANPATH = [ "/man" "/share/man" ]; };
description = ''
Attribute set of environment variable. Each attribute maps to a list
of relative paths. Each relative path is appended to the each 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 <option>environment.profiles</option> to form the content of the
corresponding environment variable.
'';
@ -123,6 +123,7 @@ in
"''${pkgs.dash}/bin/dash"
'';
type = types.path;
visible = false;
description = ''
The shell executable that is linked system-wide to
<literal>/bin/sh</literal>. Please note that NixOS assumes all

View File

@ -33,7 +33,7 @@ in
echo "unpacking the NixOS/Nixpkgs sources..."
mkdir -p /nix/var/nix/profiles/per-user/root
${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/per-user/root/channels \
-i ${channelSources} --quiet --option use-substitutes false
-i ${channelSources} --quiet --option build-use-substitutes false
mkdir -m 0700 -p /root/.nix-defexpr
ln -s /nix/var/nix/profiles/per-user/root/channels /root/.nix-defexpr/channels
mkdir -m 0755 -p /var/lib/nixos

View File

@ -188,6 +188,9 @@ mkdir -m 0755 -p $mountPoint/bin
ln -sf @shell@ $mountPoint/bin/sh
# Build hooks likely won't function correctly in the minimal chroot; just disable them.
unset NIX_BUILD_HOOK
# Make the build below copy paths from the CD if possible. Note that
# /tmp/root in the chroot is the root of the CD.
export NIX_OTHER_STORES=/tmp/root/nix:$NIX_OTHER_STORES

View File

@ -157,9 +157,9 @@ if [ -n "$buildNix" ]; then
if ! nix-build '<nixpkgs>' -A nix -o $tmpDir/nix "${extraBuildFlags[@]}" > /dev/null; then
machine="$(uname -m)"
if [ "$machine" = x86_64 ]; then
nixStorePath=/nix/store/664kxr14kfgx4dl095crvmr7pbh9xlh5-nix-1.9
nixStorePath=/nix/store/xryr9g56h8yjddp89d6dw12anyb4ch7c-nix-1.10
elif [[ "$machine" =~ i.86 ]]; then
nixStorePath=/nix/store/p7xdvz72xx3rhm121jclsbdmmcds7xh6-nix-1.9
nixStorePath=/nix/store/2w92k5wlpspf0q2k9mnf2z42prx3bwmv-nix-1.10
else
echo "$0: unsupported platform"
exit 1

View File

@ -233,6 +233,7 @@
dnschain = 209;
#lxd = 210; # unused
kibana = 211;
xtreemfs = 212;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -444,6 +445,7 @@
#dnschain = 209; #unused
lxd = 210; # unused
#kibana = 211;
xtreemfs = 212;
# When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal

View File

@ -257,6 +257,7 @@
./services/network-filesystems/diod.nix
./services/network-filesystems/u9fs.nix
./services/network-filesystems/yandex-disk.nix
./services/network-filesystems/xtreemfs.nix
./services/networking/aiccu.nix
./services/networking/amuled.nix
./services/networking/asterisk.nix
@ -472,6 +473,7 @@
./tasks/filesystems/ntfs.nix
./tasks/filesystems/reiserfs.nix
./tasks/filesystems/unionfs-fuse.nix
./tasks/filesystems/vboxsf.nix
./tasks/filesystems/vfat.nix
./tasks/filesystems/xfs.nix
./tasks/filesystems/zfs.nix

View File

@ -36,7 +36,6 @@ in
askPassword = mkOption {
type = types.str;
default = "${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass";
description = ''Program used by SSH to ask for passwords.'';
};
@ -223,5 +222,7 @@ in
export SSH_ASKPASS=${askPassword}
'';
programs.ssh.askPassword = mkDefault "${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass";
};
}

View File

@ -99,7 +99,6 @@ in
};
outputTheme = mkOption {
default = "${pkgs.venus}/themes/classic_fancy";
type = types.path;
description = ''
Directory containing a config.ini file which is merged with this one.
@ -170,5 +169,7 @@ in
startAt = cfg.dates;
};
services.venus.outputTheme = mkDefault "${pkgs.venus}/themes/classic_fancy";
};
}

View File

@ -32,7 +32,6 @@ in {
'';
};
configurationDir = mkOption {
default = "${activemq}/conf";
description = ''
The base directory for ActiveMQ's configuration.
By default, this directory is searched for a file named activemq.xml,
@ -126,6 +125,8 @@ in {
'';
};
services.activemq.configurationDir = mkDefault "${activemq}/conf";
};
}

View File

@ -5,10 +5,7 @@ with lib;
let
cfg = config.services.opentsdb;
configFile = pkgs.writeText "opentsdb.conf" ''
tsd.core.auto_create_metrics = true
tsd.http.request.enable_chunked = true
'';
configFile = pkgs.writeText "opentsdb.conf" cfg.config;
in {
@ -59,6 +56,17 @@ in {
'';
};
config = mkOption {
type = types.lines;
default = ''
tsd.core.auto_create_metrics = true
tsd.http.request.enable_chunked = true
'';
description = ''
The contents of OpenTSDB's configuration file
'';
};
};
};

View File

@ -36,7 +36,6 @@ in
hardware.sane.configDir = mkOption {
type = types.string;
default = "${saneConfig}/etc/sane.d";
description = "The value of SANE_CONFIG_DIR.";
};
@ -47,6 +46,8 @@ in
config = mkIf config.hardware.sane.enable {
hardware.sane.configDir = mkDefault "${saneConfig}/etc/sane.d";
environment.systemPackages = backends;
environment.sessionVariables = {
SANE_CONFIG_DIR = config.hardware.sane.configDir;

View File

@ -84,10 +84,10 @@ in
type = types.lines;
default = ''stdin { type => "example" }'';
description = "Logstash input configuration.";
example = ''
example = literalExample ''
# Read from journal
pipe {
command => "${pkgs.systemd}/bin/journalctl -f -o json"
command => "''${pkgs.systemd}/bin/journalctl -f -o json"
type => "syslog" codec => json {}
}
'';

View File

@ -77,7 +77,8 @@ let
smtpd_tls_key_file = ${cfg.sslKey}
smtpd_use_tls = yes
''
+ optionalString (cfg.recipientDelimiter != "") ''
recipient_delimiter = ${cfg.recipientDelimiter}
''
+ optionalString (cfg.virtual != "") ''

View File

@ -80,7 +80,6 @@ in
services.nixosManual.browser = mkOption {
type = types.path;
default = "${pkgs.w3m}/bin/w3m";
description = ''
Browser used to show the manual.
'';
@ -93,7 +92,7 @@ in
system.build.manual = manual;
environment.systemPackages = [ manual.manpages help ];
environment.systemPackages = [ manual.manpages manual.manual help ];
boot.extraTTYs = mkIf cfg.showManual ["tty${cfg.ttyNumber}"];
@ -116,6 +115,8 @@ in
services.mingetty.helpLine = mkIf cfg.showManual
"\nPress <Alt-F${toString cfg.ttyNumber}> for the NixOS manual.";
services.nixosManual.browser = mkDefault "${pkgs.w3m}/bin/w3m";
};
}

View File

@ -97,7 +97,6 @@ in
transcoders = mkOption {
type = types.listOf types.path;
default = [ "${pkgs.ffmpeg}/bin/ffmpeg" ];
description = ''
List of paths to transcoder executables that should be accessible
from Subsonic. Symlinks will be created to each executable inside
@ -153,5 +152,8 @@ in
};
users.extraGroups.subsonic.gid = config.ids.gids.subsonic;
services.subsonic.transcoders = mkDefault [ "${pkgs.ffmpeg}/bin/ffmpeg" ];
};
}

View File

@ -200,7 +200,6 @@ in {
staticRootPath = mkOption {
description = "Root path for static assets.";
default = "${cfg.package.out}/share/go/src/github.com/grafana/grafana/public";
type = types.str;
};
@ -311,7 +310,7 @@ in {
config = mkIf cfg.enable {
warnings = [
"Grafana passwords will be stored as plaintext in nix store!"
"Grafana passwords will be stored as plaintext in the Nix store!"
];
systemd.services.grafana = {
@ -331,5 +330,8 @@ in {
home = cfg.dataDir;
createHome = true;
};
services.grafana.staticRootPath = mkDefault "${cfg.package.out}/share/go/src/github.com/grafana/grafana/public";
};
}

View File

@ -0,0 +1,469 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.xtreemfs;
xtreemfs = pkgs.xtreemfs;
home = cfg.homeDir;
startupScript = class: configPath: pkgs.writeScript "xtreemfs-osd.sh" ''
#! ${pkgs.stdenv.shell}
JAVA_HOME="${pkgs.jdk}"
JAVADIR="${xtreemfs}/share/java"
JAVA_CALL="$JAVA_HOME/bin/java -ea -cp $JAVADIR/XtreemFS.jar:$JAVADIR/BabuDB.jar:$JAVADIR/Flease.jar:$JAVADIR/protobuf-java-2.5.0.jar:$JAVADIR/Foundation.jar:$JAVADIR/jdmkrt.jar:$JAVADIR/jdmktk.jar:$JAVADIR/commons-codec-1.3.jar"
$JAVA_CALL ${class} ${configPath}
'';
dirReplicationConfig = pkgs.writeText "xtreemfs-dir-replication-plugin.properties" ''
babudb.repl.backupDir = ${home}/server-repl-dir
plugin.jar = ${xtreemfs}/share/java/BabuDB_replication_plugin.jar
babudb.repl.dependency.0 = ${xtreemfs}/share/java/Flease.jar
${cfg.dir.replication.extraConfig}
'';
dirConfig = pkgs.writeText "xtreemfs-dir-config.properties" ''
uuid = ${cfg.dir.uuid}
listen.port = ${toString cfg.dir.port}
${optionalString (cfg.dir.address != "") "listen.address = ${cfg.dir.address}"}
http_port = ${toString cfg.dir.httpPort}
babudb.baseDir = ${home}/dir/database
babudb.logDir = ${home}/dir/db-log
babudb.sync = ${if cfg.dir.replication.enable then "FDATASYNC" else cfg.dir.syncMode}
${optionalString cfg.dir.replication.enable "babudb.plugin.0 = ${dirReplicationConfig}"}
${cfg.dir.extraConfig}
'';
mrcReplicationConfig = pkgs.writeText "xtreemfs-mrc-replication-plugin.properties" ''
babudb.repl.backupDir = ${home}/server-repl-mrc
plugin.jar = ${xtreemfs}/share/java/BabuDB_replication_plugin.jar
babudb.repl.dependency.0 = ${xtreemfs}/share/java/Flease.jar
${cfg.mrc.replication.extraConfig}
'';
mrcConfig = pkgs.writeText "xtreemfs-mrc-config.properties" ''
uuid = ${cfg.mrc.uuid}
listen.port = ${toString cfg.mrc.port}
${optionalString (cfg.mrc.address != "") "listen.address = ${cfg.mrc.address}"}
http_port = ${toString cfg.mrc.httpPort}
babudb.baseDir = ${home}/mrc/database
babudb.logDir = ${home}/mrc/db-log
babudb.sync = ${if cfg.mrc.replication.enable then "FDATASYNC" else cfg.mrc.syncMode}
${optionalString cfg.mrc.replication.enable "babudb.plugin.0 = ${mrcReplicationConfig}"}
${cfg.mrc.extraConfig}
'';
osdConfig = pkgs.writeText "xtreemfs-osd-config.properties" ''
uuid = ${cfg.osd.uuid}
listen.port = ${toString cfg.osd.port}
${optionalString (cfg.osd.address != "") "listen.address = ${cfg.osd.address}"}
http_port = ${toString cfg.osd.httpPort}
object_dir = ${home}/osd/
${cfg.osd.extraConfig}
'';
optionalDir = optionals cfg.dir.enable ["xtreemfs-dir.service"];
systemdOptionalDependencies = {
after = [ "network.target" ] ++ optionalDir;
wantedBy = [ "multi-user.target" ] ++ optionalDir;
};
in
{
###### interface
options = {
services.xtreemfs = {
enable = mkEnableOption "XtreemFS";
homeDir = mkOption {
default = "/var/lib/xtreemfs";
description = ''
XtreemFS home dir for the xtreemfs user.
'';
};
dir = {
enable = mkOption {
default = true;
description = ''
Whether to enable XtreemFS DIR service.
'';
};
uuid = mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e40";
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `utillinux` package.
'';
};
port = mkOption {
default = 32638;
description = ''
The port to listen on for incoming connections (TCP).
'';
};
address = mkOption {
example = "127.0.0.1";
default = "";
description = ''
If specified, it defines the interface to listen on. If not
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
default = 30638;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
syncMode = mkOption {
default = "FSYNC";
example = "FDATASYNC";
description = ''
The sync mode influences how operations are committed to the disk
log before the operation is acknowledged to the caller.
-ASYNC mode the writes to the disk log are buffered in memory by the operating system. This is the fastest mode but will lead to data loss in case of a crash, kernel panic or power failure.
-SYNC_WRITE_METADATA opens the file with O_SYNC, the system will not buffer any writes. The operation will be acknowledged when data has been safely written to disk. This mode is slow but offers maximum data safety. However, BabuDB cannot influence the disk drive caches, this depends on the OS and hard disk model.
-SYNC_WRITE similar to SYNC_WRITE_METADATA but opens file with O_DSYNC which means that only the data is commit to disk. This can lead to some data loss depending on the implementation of the underlying file system. Linux does not implement this mode.
-FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk.
-FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk.
For best throughput use ASYNC, for maximum data safety use FSYNC.
(If xtreemfs.dir.replication.enable is true then FDATASYNC is forced)
'';
};
extraConfig = mkOption {
default = "";
example = ''
# specify whether SSL is required
ssl.enabled = true
ssl.service_creds.pw = passphrase
ssl.service_creds.container = pkcs12
ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/dir.p12
ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
ssl.trusted_certs.pw = jks_passphrase
ssl.trusted_certs.container = jks
'';
description = ''
Configuration of XtreemFS DIR service.
WARNING: configuration is saved as plaintext inside nix store.
For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
'';
};
replication = {
enable = mkEnableOption "XtreemFS DIR replication plugin";
extraConfig = mkOption {
example = ''
# participants of the replication including this replica
babudb.repl.participant.0 = 192.168.0.10
babudb.repl.participant.0.port = 35676
babudb.repl.participant.1 = 192.168.0.11
babudb.repl.participant.1.port = 35676
babudb.repl.participant.2 = 192.168.0.12
babudb.repl.participant.2.port = 35676
# number of servers that at least have to be up to date
# To have a fault-tolerant system, this value has to be set to the
# majority of nodes i.e., if you have three replicas, set this to 2
# Please note that a setup with two nodes provides no fault-tolerance.
babudb.repl.sync.n = 2
# specify whether SSL is required
babudb.ssl.enabled = true
babudb.ssl.protocol = tlsv12
# server credentials for SSL handshakes
babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
babudb.ssl.service_creds.pw = passphrase
babudb.ssl.service_creds.container = pkcs12
# trusted certificates for SSL handshakes
babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
babudb.ssl.trusted_certs.pw = jks_passphrase
babudb.ssl.trusted_certs.container = jks
babudb.ssl.authenticationWithoutEncryption = false
'';
description = ''
Configuration of XtreemFS DIR replication plugin.
WARNING: configuration is saved as plaintext inside nix store.
For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
'';
};
};
};
mrc = {
enable = mkOption {
default = true;
description = ''
Whether to enable XtreemFS MRC service.
'';
};
uuid = mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e41";
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `utillinux` package.
'';
};
port = mkOption {
default = 32636;
description = ''
The port to listen on for incoming connections (TCP).
'';
};
address = mkOption {
example = "127.0.0.1";
default = "";
description = ''
If specified, it defines the interface to listen on. If not
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
default = 30636;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
syncMode = mkOption {
default = "FSYNC";
example = "FDATASYNC";
description = ''
The sync mode influences how operations are committed to the disk
log before the operation is acknowledged to the caller.
-ASYNC mode the writes to the disk log are buffered in memory by the operating system. This is the fastest mode but will lead to data loss in case of a crash, kernel panic or power failure.
-SYNC_WRITE_METADATA opens the file with O_SYNC, the system will not buffer any writes. The operation will be acknowledged when data has been safely written to disk. This mode is slow but offers maximum data safety. However, BabuDB cannot influence the disk drive caches, this depends on the OS and hard disk model.
-SYNC_WRITE similar to SYNC_WRITE_METADATA but opens file with O_DSYNC which means that only the data is commit to disk. This can lead to some data loss depending on the implementation of the underlying file system. Linux does not implement this mode.
-FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk.
-FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk.
For best throughput use ASYNC, for maximum data safety use FSYNC.
(If xtreemfs.mrc.replication.enable is true then FDATASYNC is forced)
'';
};
extraConfig = mkOption {
example = ''
osd_check_interval = 300
no_atime = true
local_clock_renewal = 0
remote_time_sync = 30000
authentication_provider = org.xtreemfs.common.auth.NullAuthProvider
# shared secret between the MRC and all OSDs
capability_secret = iNG8UuQJrJ6XVDTe
dir_service.host = 192.168.0.10
dir_service.port = 32638
# if replication is enabled
dir_service.1.host = 192.168.0.11
dir_service.1.port = 32638
dir_service.2.host = 192.168.0.12
dir_service.2.port = 32638
# specify whether SSL is required
ssl.enabled = true
ssl.protocol = tlsv12
ssl.service_creds.pw = passphrase
ssl.service_creds.container = pkcs12
ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/mrc.p12
ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
ssl.trusted_certs.pw = jks_passphrase
ssl.trusted_certs.container = jks
'';
description = ''
Configuration of XtreemFS MRC service.
WARNING: configuration is saved as plaintext inside nix store.
For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
'';
};
replication = {
enable = mkEnableOption "XtreemFS MRC replication plugin";
extraConfig = mkOption {
example = ''
# participants of the replication including this replica
babudb.repl.participant.0 = 192.168.0.10
babudb.repl.participant.0.port = 35678
babudb.repl.participant.1 = 192.168.0.11
babudb.repl.participant.1.port = 35678
babudb.repl.participant.2 = 192.168.0.12
babudb.repl.participant.2.port = 35678
# number of servers that at least have to be up to date
# To have a fault-tolerant system, this value has to be set to the
# majority of nodes i.e., if you have three replicas, set this to 2
# Please note that a setup with two nodes provides no fault-tolerance.
babudb.repl.sync.n = 2
# specify whether SSL is required
babudb.ssl.enabled = true
babudb.ssl.protocol = tlsv12
# server credentials for SSL handshakes
babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
babudb.ssl.service_creds.pw = passphrase
babudb.ssl.service_creds.container = pkcs12
# trusted certificates for SSL handshakes
babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
babudb.ssl.trusted_certs.pw = jks_passphrase
babudb.ssl.trusted_certs.container = jks
babudb.ssl.authenticationWithoutEncryption = false
'';
description = ''
Configuration of XtreemFS MRC replication plugin.
WARNING: configuration is saved as plaintext inside nix store.
For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
'';
};
};
};
osd = {
enable = mkOption {
default = true;
description = ''
Whether to enable XtreemFS OSD service.
'';
};
uuid = mkOption {
example = "eacb6bab-f444-4ebf-a06a-3f72d7465e42";
description = ''
Must be set to a unique identifier, preferably a UUID according to
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
the `utillinux` package.
'';
};
port = mkOption {
default = 32640;
description = ''
The port to listen on for incoming connections (TCP and UDP).
'';
};
address = mkOption {
example = "127.0.0.1";
default = "";
description = ''
If specified, it defines the interface to listen on. If not
specified, the service will listen on all interfaces (any).
'';
};
httpPort = mkOption {
default = 30640;
description = ''
Specifies the listen port for the HTTP service that returns the
status page.
'';
};
extraConfig = mkOption {
example = ''
local_clock_renewal = 0
remote_time_sync = 30000
report_free_space = true
capability_secret = iNG8UuQJrJ6XVDTe
dir_service.host = 192.168.0.10
dir_service.port = 32638
# if replication is used
dir_service.1.host = 192.168.0.11
dir_service.1.port = 32638
dir_service.2.host = 192.168.0.12
dir_service.2.port = 32638
# specify whether SSL is required
ssl.enabled = true
ssl.service_creds.pw = passphrase
ssl.service_creds.container = pkcs12
ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
ssl.trusted_certs.pw = jks_passphrase
ssl.trusted_certs.container = jks
'';
description = ''
Configuration of XtreemFS OSD service.
WARNING: configuration is saved as plaintext inside nix store.
For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
'';
};
};
};
};
###### implementation
config = lib.mkIf cfg.enable {
environment.systemPackages = [ xtreemfs ];
users.extraUsers.xtreemfs =
{ uid = config.ids.uids.xtreemfs;
description = "XtreemFS user";
createHome = true;
home = home;
};
users.extraGroups.xtreemfs =
{ gid = config.ids.gids.xtreemfs;
};
systemd.services.xtreemfs-dir = mkIf cfg.dir.enable {
description = "XtreemFS-DIR Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "xtreemfs";
ExecStart = "${startupScript "org.xtreemfs.dir.DIR" dirConfig}";
};
};
systemd.services.xtreemfs-mrc = mkIf cfg.mrc.enable ({
description = "XtreemFS-MRC Server";
serviceConfig = {
User = "xtreemfs";
ExecStart = "${startupScript "org.xtreemfs.mrc.MRC" mrcConfig}";
};
} // systemdOptionalDependencies);
systemd.services.xtreemfs-osd = mkIf cfg.osd.enable ({
description = "XtreemFS-OSD Server";
serviceConfig = {
User = "xtreemfs";
ExecStart = "${startupScript "org.xtreemfs.osd.OSD" osdConfig}";
};
} // systemdOptionalDependencies);
};
}

View File

@ -24,6 +24,8 @@ let
pid-file "/var/run/named/named.pid";
};
${cfg.extraConfig}
${ concatMapStrings
({ name, file, master ? true, slaves ? [], masters ? [] }:
''
@ -110,6 +112,13 @@ in
}];
};
extraConfig = mkOption {
default = "";
description = "
Extra lines to be added verbatim to the generated named configuration file.
";
};
configFile = mkOption {
default = confFile;
description = "

View File

@ -18,6 +18,7 @@ let
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.vswitches))
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds))
++ config.networking.dhcpcd.denyInterfaces;

View File

@ -52,10 +52,7 @@ in
default = "opendns";
type = types.nullOr types.string;
description = ''
The name of the upstream DNSCrypt resolver to use. See
<literal>${resolverListFile}</literal> for alternative resolvers
(e.g., if you are concerned about logging and/or server
location).
The name of the upstream DNSCrypt resolver to use.
'';
};
customResolver = mkOption {

View File

@ -33,7 +33,7 @@ in
type = types.str;
description = "
The Seeks server configuration. If it is not specified,
a default configuration is used (${seeks}/etc/seeks).
a default configuration is used.
";
};

View File

@ -54,12 +54,15 @@ in
description = "Syncthing service";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment.STNORESTART = "placeholder"; # do not self-restart
environment.STNORESTART = "yes"; # do not self-restart
environment.STNOUPGRADE = "yes";
serviceConfig = {
User = "${cfg.user}";
PermissionsStartOnly = true;
Restart = "always";
Restart = "on-failure";
ExecStart = "${pkgs.syncthing}/bin/syncthing -no-browser -home=${cfg.dataDir}";
SuccessExitStatus = "2 3 4";
RestartForceExitStatus="3 4";
};
};

View File

@ -44,8 +44,7 @@ in {
phpIni = mkOption {
type = types.path;
default = "${cfg.phpPackage}/etc/php-recommended.ini";
description = "php.ini file to use.";
description = "PHP configuration file to use.";
};
poolConfigs = mkOption {
@ -86,5 +85,7 @@ in {
};
};
services.phpfpm.phpIni = mkDefault "${cfg.phpPackage}/etc/php-recommended.ini";
};
}

View File

@ -114,6 +114,10 @@ let
rm -rf $HOME/.compose-cache
mkdir $HOME/.compose-cache
# Work around KDE errors when a user first logs in and
# .local/share doesn't exist yet.
mkdir -p $HOME/.local/share
${cfg.displayManager.sessionCommands}
# Allow the user to execute commands at the beginning of the X session.

View File

@ -106,7 +106,7 @@ in
systemd.services.display-manager.wants = [ "systemd-machined.service" ];
systemd.services.display-manager.after = [ "systemd-machined.service" ];
systemd.services.display-manager.path = [ gnome3.gnome_shell gnome3.caribou pkgs.xlibs.xhost pkgs.dbus_tools ];
systemd.services.display-manager.path = [ gnome3.gnome_shell gnome3.caribou pkgs.xorg.xhost pkgs.dbus_tools ];
services.dbus.packages = [ gdm ];

View File

@ -19,7 +19,7 @@ let
''}
[X-*-Core]
Xrdb=${pkgs.xlibs.xrdb}/bin/xrdb
Xrdb=${pkgs.xorg.xrdb}/bin/xrdb
SessionsDirs=${dmcfg.session.desktops}
Session=${dmcfg.session.script}
FailsafeClient=${pkgs.xterm}/bin/xterm

View File

@ -104,7 +104,6 @@ in
};
background = mkOption {
default = "${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png";
description = ''
The background image or color to use.
'';
@ -172,5 +171,8 @@ in
};
users.extraGroups.lightdm.gid = config.ids.gids.lightdm;
services.xserver.displayManager.lightdm.background = mkDefault "${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png";
};
}

View File

@ -18,6 +18,8 @@ let cfg = config.services.xserver.synaptics;
Option "TapButton2" "0"
Option "TapButton3" "0"
'';
pkg = pkgs.xorg.xf86inputsynaptics;
etcFile = "X11/xorg.conf.d/50-synaptics.conf";
in {
options = {
@ -146,9 +148,12 @@ in {
config = mkIf cfg.enable {
services.xserver.modules = [ pkgs.xorg.xf86inputsynaptics ];
services.xserver.modules = [ pkg ];
environment.systemPackages = [ pkgs.xorg.xf86inputsynaptics ];
environment.etc."${etcFile}".source =
"${pkg}/share/X11/xorg.conf.d/50-synaptics.conf";
environment.systemPackages = [ pkg ];
services.xserver.config =
''

View File

@ -135,7 +135,7 @@ ln -s @modulesClosure@/lib/modules /lib/modules
echo @extraUtils@/bin/modprobe > /proc/sys/kernel/modprobe
for i in @kernelModules@; do
echo "loading module $(basename $i)..."
modprobe $i || true
modprobe $i
done
@ -146,7 +146,7 @@ ln -sfn @udevRules@ /etc/udev/rules.d
mkdir -p /dev/.mdadm
systemd-udevd --daemon
udevadm trigger --action=add
udevadm settle || true
udevadm settle
# Load boot-time keymap before any LVM/LUKS initialization
@ -290,10 +290,23 @@ mountFS() {
if [ -z "$fsType" ]; then fsType=auto; fi
fi
echo "$device /mnt-root$mountPoint $fsType $options" >> /etc/fstab
# Filter out x- options, which busybox doesn't do yet.
local optionsFiltered="$(IFS=,; for i in $options; do if [ "${i:0:2}" != "x-" ]; then echo -n $i,; fi; done)"
echo "$device /mnt-root$mountPoint $fsType $optionsFiltered" >> /etc/fstab
checkFS "$device" "$fsType"
# Optionally resize the filesystem.
case $options in
*x-nixos.autoresize*)
if [ "$fsType" = ext2 -o "$fsType" = ext3 -o "$fsType" = ext4 ]; then
echo "resizing $device..."
resize2fs "$device"
fi
;;
esac
# Create backing directories for unionfs-fuse.
if [ "$fsType" = unionfs-fuse ]; then
for i in $(IFS=:; echo ${options##*,dirs=}); do
@ -303,7 +316,7 @@ mountFS() {
echo "mounting $device on $mountPoint..."
mkdir -p "/mnt-root$mountPoint" || true
mkdir -p "/mnt-root$mountPoint"
# For CIFS mounts, retry a few times before giving up.
local n=0
@ -375,7 +388,7 @@ while read -u 3 mountPoint; do
# Wait once more for the udev queue to empty, just in case it's
# doing something with $device right now.
udevadm settle || true
udevadm settle
mountFS "$device" "$mountPoint" "$options" "$fsType"
done
@ -388,9 +401,9 @@ exec 3>&-
# 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)
eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=/mnt-root/iso)
else
eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=$targetRoot || true)
eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=$targetRoot)
fi
if [ "$ROOT_MAJOR" -a "$ROOT_MINOR" -a "$ROOT_MAJOR" != 0 ]; then
mkdir -p /run/udev/rules.d
@ -399,7 +412,7 @@ fi
# Stop udevd.
udevadm control --exit || true
udevadm control --exit
# Kill any remaining processes, just to be sure we're not taking any
# with us into stage 2. But keep storage daemons like unionfs-fuse.

View File

@ -70,6 +70,12 @@ let
copy_bin_and_libs ${pkgs.kmod}/bin/kmod
ln -sf kmod $out/bin/modprobe
# Copy resize2fs if needed.
${optionalString (any (fs: fs.autoResize) (attrValues config.fileSystems)) ''
# We need mke2fs in the initrd.
copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs
''}
${config.boot.initrd.extraUtilsCommands}
# Copy ld manually since it isn't detected correctly
@ -393,7 +399,6 @@ in
}
];
system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk;
system.build.extraUtils = extraUtils;

View File

@ -444,6 +444,17 @@ in
'';
};
systemd.generators = mkOption {
type = types.attrsOf types.path;
default = {};
example = { "systemd-gpt-auto-generator" = "/dev/null"; };
description = ''
Definition of systemd generators.
For each <literal>NAME = VALUE</literal> pair of the attrSet, a link is generated from
<literal>/etc/systemd/system-generators/NAME</literal> to <literal>VALUE</literal>.
'';
};
systemd.defaultUnit = mkOption {
default = "multi-user.target";
type = types.str;
@ -600,20 +611,17 @@ in
environment.systemPackages = [ systemd ];
environment.etc."systemd/system".source =
generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
environment.etc = {
"systemd/system".source = generateUnits "system" cfg.units upstreamSystemUnits upstreamSystemWants;
environment.etc."systemd/user".source =
generateUnits "user" cfg.user.units upstreamUserUnits [];
"systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits [];
environment.etc."systemd/system.conf".text =
''
"systemd/system.conf".text = ''
[Manager]
${config.systemd.extraConfig}
'';
environment.etc."systemd/journald.conf".text =
''
"systemd/journald.conf".text = ''
[Journal]
RateLimitInterval=${config.services.journald.rateLimitInterval}
RateLimitBurst=${toString config.services.journald.rateLimitBurst}
@ -624,17 +632,26 @@ in
${config.services.journald.extraConfig}
'';
environment.etc."systemd/logind.conf".text =
''
"systemd/logind.conf".text = ''
[Login]
${config.services.logind.extraConfig}
'';
environment.etc."systemd/sleep.conf".text =
''
"systemd/sleep.conf".text = ''
[Sleep]
'';
"tmpfiles.d/systemd.conf".source = "${systemd}/example/tmpfiles.d/systemd.conf";
"tmpfiles.d/x11.conf".source = "${systemd}/example/tmpfiles.d/x11.conf";
"tmpfiles.d/nixos.conf".text = ''
# This file is created automatically and should not be modified.
# Please change the option systemd.tmpfiles.rules instead.
${concatStringsSep "\n" cfg.tmpfiles.rules}
'';
} // mapAttrs' (n: v: nameValuePair "systemd/system-generators/${n}" {"source"=v;}) cfg.generators;
system.activationScripts.systemd = stringAfter [ "groups" ]
''
mkdir -m 0755 -p /var/lib/udev
@ -735,17 +752,6 @@ in
startSession = true;
};
environment.etc."tmpfiles.d/systemd.conf".source = "${systemd}/example/tmpfiles.d/systemd.conf";
environment.etc."tmpfiles.d/x11.conf".source = "${systemd}/example/tmpfiles.d/x11.conf";
environment.etc."tmpfiles.d/nixos.conf".text =
''
# This file is created automatically and should not be modified.
# Please change the option systemd.tmpfiles.rules instead.
${concatStringsSep "\n" cfg.tmpfiles.rules}
'';
# Some overrides to upstream units.
systemd.services."systemd-backlight@".restartIfChanged = false;
systemd.services."systemd-rfkill@".restartIfChanged = false;

View File

@ -6,6 +6,7 @@ let
fileSystems = attrValues config.fileSystems ++ config.swapDevices;
encDevs = filter (dev: dev.encrypted.enable) fileSystems;
keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs;
keylessEncDevs = filter (dev: dev.encrypted.keyFile == null) encDevs;
isIn = needle: haystack: filter (p: p == needle) haystack != [];
anyEncrypted =
fold (j: v: v || j.encrypted.enable) false encDevs;
@ -29,15 +30,15 @@ let
label = mkOption {
default = null;
example = "rootfs";
type = types.nullOr types.str;
description = "Label of the backing encrypted device.";
type = types.uniq (types.nullOr types.str);
description = "Label of the unlocked encrypted device. Set <literal>fileSystems.&lt;name?&gt;.device</literal> to <literal>/dev/mapper/&lt;label&gt;</literal> to mount the unlocked device.";
};
keyFile = mkOption {
default = null;
example = "/root/.swapkey";
type = types.nullOr types.str;
description = "File system location of keyfile.";
description = "File system location of keyfile. This unlocks the drive after the root has been mounted to <literal>/mnt-root</literal>.";
};
};
};
@ -58,11 +59,11 @@ in
boot.initrd = {
luks = {
devices =
map (dev: { name = dev.encrypted.label; device = dev.encrypted.blkDev; } ) encDevs;
map (dev: { name = dev.encrypted.label; device = dev.encrypted.blkDev; } ) keylessEncDevs;
cryptoModules = [ "aes" "sha256" "sha1" "xts" ];
};
postMountCommands =
concatMapStrings (dev: "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.label};\n") keyedEncDevs;
concatMapStrings (dev: "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n") keyedEncDevs;
};
};
}

View File

@ -7,7 +7,7 @@ let
fileSystems = attrValues config.fileSystems;
prioOption = prio: optionalString (prio !=null) " pri=${toString prio}";
prioOption = prio: optionalString (prio != null) " pri=${toString prio}";
fileSystemOpts = { name, config, ... }: {
@ -41,9 +41,9 @@ let
};
options = mkOption {
default = "defaults,relatime";
default = "defaults";
example = "data=journal";
type = types.commas;
type = types.commas; # FIXME: should be a list
description = "Options used to mount the file system.";
};
@ -58,6 +58,17 @@ let
'';
};
autoResize = mkOption {
default = false;
type = types.bool;
description = ''
If set, the filesystem is grown to its maximum size before
being mounted. (This is typically the size of the containing
partition.) This is currently only supported for ext2/3/4
filesystems that are mounted during early boot.
'';
};
noCheck = mkOption {
default = false;
type = types.bool;
@ -69,6 +80,7 @@ let
config = {
mountPoint = mkDefault name;
device = mkIf (config.fsType == "tmpfs") (mkDefault config.fsType);
options = mkIf config.autoResize "x-nixos.autoresize";
};
};
@ -141,7 +153,7 @@ in
environment.etc.fstab.text =
let
fsToSkipCheck = [ "none" "btrfs" "zfs" "tmpfs" "nfs" ];
fsToSkipCheck = [ "none" "btrfs" "zfs" "tmpfs" "nfs" "vboxsf" ];
skipCheck = fs: fs.noCheck || fs.device == "none" || builtins.elem fs.fsType fsToSkipCheck;
in ''
# This is a generated file. Do not edit!

View File

@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
with lib;
let
inInitrd = any (fs: fs == "vboxsf") config.boot.initrd.supportedFilesystems;
package = pkgs.runCommand "mount.vboxsf" {} ''
mkdir -p $out/bin
cp ${pkgs.linuxPackages.virtualboxGuestAdditions}/bin/mount.vboxsf $out/bin
'';
in
{
config = mkIf (any (fs: fs == "vboxsf") config.boot.supportedFilesystems) {
system.fsPackages = [ package ];
boot.initrd.kernelModules = mkIf inInitrd [ "vboxsf" ];
};
}

View File

@ -21,9 +21,9 @@ let
kernel = config.boot.kernelPackages;
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;
splKernelPkg = kernel.spl;
zfsKernelPkg = kernel.zfs;
zfsUserPkg = pkgs.zfs;
autosnapPkg = pkgs.zfstools.override {
zfs = zfsUserPkg;
@ -53,16 +53,6 @@ in
options = {
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;

View File

@ -220,6 +220,45 @@ in
'';
});
createVswitchDevice = n: v: nameValuePair "${n}-netdev"
(let
managedInterfaces = filter (x: hasAttr x cfg.interfaces) v.interfaces;
managedInterfaceServices = concatMap (i: [ "network-addresses-${i}.service" "network-link-${i}.service" ]) managedInterfaces;
virtualInterfaces = filter (x: (hasAttr x cfg.interfaces) && cfg.interfaces.${x}.virtual) v.interfaces;
virtualInterfaceServices = concatMap (i: [ "${i}-netdev.service" ]) virtualInterfaces;
deps = map subsystemDevice v.interfaces;
ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules;
in
{ description = "Open vSwitch Interface ${n}";
wantedBy = [ "network.target" "vswitchd.service" (subsystemDevice n) ];
requires = optionals v.bindInterfaces (deps ++ managedInterfaceServices ++ virtualInterfaceServices);
requiredBy = optionals v.bindInterfaces (managedInterfaceServices ++ virtualInterfaceServices);
bindsTo = deps ++ [ "vswitchd.service" ];
partOf = [ "vswitchd.service" ];
after = [ "network-pre.target" "vswitchd.service" ] ++ deps ++ managedInterfaceServices ++ virtualInterfaceServices;
before = [ "network-interfaces.target" (subsystemDevice n) ];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute config.virtualisation.vswitch.package ];
script = ''
echo "Removing old Open vSwitch ${n}..."
ovs-vsctl --if-exists del-br ${n}
echo "Adding Open vSwitch ${n}..."
ovs-vsctl -- add-br ${n} ${concatMapStrings (i: " -- add-port ${n} ${i}") v.interfaces} \
${concatMapStrings (x: " -- set-controller ${n} " + x) v.controllers} \
${concatMapStrings (x: " -- " + x) (splitString "\n" v.extraOvsctlCmds)}
echo "Adding OpenFlow rules for Open vSwitch ${n}..."
ovs-ofctl add-flows ${n} ${ofRules}
'';
postStop = ''
ip link set ${n} down || true
ovs-ofctl del-flows ${n} || true
ovs-vsctl --if-exists del-br ${n}
'';
});
createBondDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = map subsystemDevice v.interfaces;
@ -335,6 +374,7 @@ in
map configureAddrs interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges
// mapAttrs' createVswitchDevice cfg.vswitches
// mapAttrs' createBondDevice cfg.bonds
// mapAttrs' createMacvlanDevice cfg.macvlans
// mapAttrs' createSitDevice cfg.sits

View File

@ -35,6 +35,9 @@ in
assertions = [ {
assertion = cfg.defaultGatewayWindowSize == null;
message = "networking.defaultGatewayWindowSize is not supported by networkd.";
} {
assertion = cfg.vswitches == {};
message = "networking.vswichtes are not supported by networkd.";
} ] ++ flip mapAttrsToList cfg.bridges (n: { rstp, ... }: {
assertion = !rstp;
message = "networking.bridges.${n}.rstp is not supported by networkd.";

View File

@ -12,7 +12,8 @@ let
hasBonds = cfg.bonds != { };
slaves = concatMap (i: i.interfaces) (attrValues cfg.bonds)
++ concatMap (i: i.interfaces) (attrValues cfg.bridges);
++ concatMap (i: i.interfaces) (attrValues cfg.bridges)
++ concatMap (i: i.interfaces) (attrValues cfg.vswitches);
slaveIfs = map (i: cfg.interfaces.${i}) (filter (i: cfg.interfaces ? ${i}) slaves);
@ -371,6 +372,81 @@ in
options = [ interfaceOpts ];
};
networking.vswitches = mkOption {
default = { };
example =
{ vs0.interfaces = [ "eth0" "eth1" ];
vs1.interfaces = [ "eth2" "wlan0" ];
};
description =
''
This option allows you to define Open vSwitches that connect
physical networks together. The value of this option is an
attribute set. Each attribute specifies a vswitch, with the
attribute name specifying the name of the vswitch's network
interface.
'';
type = types.attrsOf types.optionSet;
options = {
interfaces = mkOption {
example = [ "eth0" "eth1" ];
type = types.listOf types.str;
description =
"The physical network interfaces connected by the vSwitch.";
};
bindInterfaces = mkOption {
type = types.bool;
default = false;
description = ''
If true, then the interfaces of the vSwitch are brought 'up' and especially
also 'down' together with the vSwitch. That requires that every interfaces
is configured as a systemd network services.
'';
};
controllers = mkOption {
type = types.listOf types.str;
default = [];
example = [ "ptcp:6653:[::1]" ];
description = ''
Specify the controller targets. For the allowed options see <literal>man 8 ovs-vsctl</literal>.
'';
};
openFlowRules = mkOption {
type = types.lines;
default = "";
example = ''
actions=normal
'';
description = ''
OpenFlow rules to insert into the Open vSwitch. All <literal>openFlowRules</literal> are
loaded with <literal>ovs-ofctl</literal> within one atomic operation.
'';
};
extraOvsctlCmds = mkOption {
type = types.lines;
default = "";
example = ''
set-fail-mode <switch_name> secure
set Bridge <switch_name> stp_enable=true
'';
description = ''
Commands to manipulate the Open vSwitch database. Every line executed with <literal>ovs-vsctl</literal>.
All commands are bundled together with the operations for adding the interfaces
into one atomic operation.
'';
};
};
};
networking.bridges = mkOption {
default = { };
example =
@ -766,6 +842,8 @@ in
services.mstpd = mkIf needsMstpd { enable = true; };
virtualisation.vswitch = mkIf (cfg.vswitches != { }) { enable = true; };
};
}

View File

@ -1,3 +0,0 @@
{
imports = [ <nixpkgs/nixos/modules/virtualisation/amazon-image.nix> ];
}

View File

@ -0,0 +1,50 @@
# This module automatically grows the root partition on Amazon EC2 HVM
# instances. This allows an instance to be created with a bigger root
# filesystem than provided by the AMI.
{ config, lib, pkgs, ... }:
with lib;
let
growpart = pkgs.stdenv.mkDerivation {
name = "growpart";
src = pkgs.fetchurl {
url = "https://launchpad.net/cloud-utils/trunk/0.27/+download/cloud-utils-0.27.tar.gz";
sha256 = "16shlmg36lidp614km41y6qk3xccil02f5n3r4wf6d1zr5n4v8vd";
};
patches = [ ./growpart-util-linux-2.26.patch ];
buildPhase = ''
cp bin/growpart $out
sed -i 's|awk|gawk|' $out
sed -i 's|sed|gnused|' $out
'';
dontInstall = true;
dontPatchShebangs = true;
};
in
{
config = mkIf config.ec2.hvm {
boot.initrd.extraUtilsCommands = ''
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
ln -s sed $out/bin/gnused
'';
boot.initrd.postDeviceCommands = ''
if [ -e /dev/xvda ] && [ -e /dev/xvda1 ]; then
TMPDIR=/run sh $(type -P growpart) /dev/xvda 1
udevadm settle
fi
'';
};
}

View File

@ -1,105 +1,40 @@
# Configuration for Amazon EC2 instances. (Note that this file is a
# misnomer - it should be "amazon-config.nix" or so, not
# "amazon-image.nix", since it's used not only to build images but
# also to reconfigure instances. However, we can't rename it because
# existing "configuration.nix" files on EC2 instances refer to it.)
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.ec2;
in
let cfg = config.ec2; in
{
imports = [ ../profiles/headless.nix ./ec2-data.nix ];
imports = [ ../profiles/headless.nix ./ec2-data.nix ./amazon-grow-partition.nix ];
config = {
system.build.amazonImage =
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "amazon-image"
{ preVM =
''
mkdir $out
diskImage=$out/nixos.img
${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "8G"
mv closure xchg/
'';
buildInputs = [ pkgs.utillinux pkgs.perl ];
exportReferencesGraph =
[ "closure" config.system.build.toplevel ];
}
''
${if cfg.hvm then ''
# Create a single / 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 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
'' else ''
# Create an empty filesystem and mount it.
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L nixos /dev/vda
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda
mkdir /mnt
mount /dev/vda /mnt
''}
# The initrd expects these directories to exist.
mkdir /mnt/dev /mnt/proc /mnt/sys
mount -o bind /proc /mnt/proc
mount -o bind /dev /mnt/dev
mount -o 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/
# 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 ""
# Create the system profile to allow nixos-rebuild to work.
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.
mkdir -p /mnt/etc
touch /mnt/etc/NIXOS
# `switch-to-configuration' requires a /bin/sh
mkdir -p /mnt/bin
ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
# Install a configuration.nix.
mkdir -p /mnt/etc/nixos
cp ${./amazon-config.nix} /mnt/etc/nixos/configuration.nix
# Generate the GRUB menu.
ln -s vda /dev/xvda
chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
umount /mnt/proc /mnt/dev /mnt/sys
umount /mnt
''
);
fileSystems."/".device = "/dev/disk/by-label/nixos";
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
};
boot.initrd.kernelModules = [ "xen-blkfront" ];
boot.kernelModules = [ "xen-netfront" ];
boot.kernelParams = mkIf cfg.hvm [ "console=ttyS0" ];
# Prevent the nouveau kernel module from being loaded, as it
# interferes with the nvidia/nvidia-uvm modules needed for CUDA.
boot.blacklistedKernelModules = [ "nouveau" ];
# Also blacklist xen_fbfront to prevent a 30 second delay during
# boot.
boot.blacklistedKernelModules = [ "nouveau" "xen_fbfront" ];
# 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";
boot.loader.grub.timeout = 0;
boot.loader.grub.extraPerEntryConfig = "root (hd0${lib.optionalString cfg.hvm ",0"})";
boot.loader.grub.extraPerEntryConfig = mkIf (!cfg.hvm) "root (hd0)";
boot.initrd.postDeviceCommands =
''

View File

@ -9,7 +9,7 @@ with lib;
{
config = {
systemd.services."fetch-ec2-data" =
systemd.services.fetch-ec2-data =
{ description = "Fetch EC2 Data";
wantedBy = [ "multi-user.target" "sshd.service" ];
@ -35,10 +35,8 @@ with lib;
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
cat /root/key.pub >> /root/.ssh/authorized_keys
echo "new key added to authorized_keys"
fi
cat /root/key.pub >> /root/.ssh/authorized_keys
echo "new key added to authorized_keys"
chmod 600 /root/.ssh/authorized_keys
rm -f /root/key.pub
fi
@ -48,13 +46,22 @@ with lib;
# the supplied user data, if available. Otherwise sshd will
# generate one normally.
$wget http://169.254.169.254/2011-01-01/user-data > /root/user-data || true
mkdir -m 0755 -p /etc/ssh
key="$(sed 's/|/\n/g; s/SSH_HOST_DSA_KEY://; t; d' /root/user-data)"
key_pub="$(sed 's/SSH_HOST_DSA_KEY_PUB://; t; d' /root/user-data)"
if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_dsa_key ]; then
mkdir -m 0755 -p /etc/ssh
(umask 077; echo "$key" > /etc/ssh/ssh_host_dsa_key)
echo "$key_pub" > /etc/ssh/ssh_host_dsa_key.pub
fi
key="$(sed 's/|/\n/g; s/SSH_HOST_ED25519_KEY://; t; d' /root/user-data)"
key_pub="$(sed 's/SSH_HOST_ED25519_KEY_PUB://; t; d' /root/user-data)"
if [ -n "$key" -a -n "$key_pub" -a ! -e /etc/ssh/ssh_host_ed25519_key ]; then
(umask 077; echo "$key" > /etc/ssh/ssh_host_ed25519_key)
echo "$key_pub" > /etc/ssh/ssh_host_ed25519_key.pub
fi
'';
serviceConfig.Type = "oneshot";
@ -71,7 +78,9 @@ with lib;
# can obtain it securely by parsing the output of
# ec2-get-console-output.
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" > /dev/console
${config.programs.ssh.package}/bin/ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub > /dev/console
for i in /etc/ssh/ssh_host_*_key.pub; do
${config.programs.ssh.package}/bin/ssh-keygen -l -f $i > /dev/console
done
echo "-----END SSH HOST KEY FINGERPRINTS-----" > /dev/console
'';
serviceConfig.Type = "oneshot";

View File

@ -0,0 +1,88 @@
From 1895d10a7539d055a4e0206af1e7a9e5ea32a4f7 Mon Sep 17 00:00:00 2001
From: Juerg Haefliger <juerg.haefliger@hp.com>
Date: Wed, 25 Mar 2015 13:59:20 +0100
Subject: [PATCH] Support new sfdisk version 2.26
The sfdisk usage with version 2.26 changed. Specifically, the option
--show-pt-geometry and functionality for CHS have been removed.
Also, restoring a backup MBR now needs to be done using dd.
---
bin/growpart | 28 ++++++++++------------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/bin/growpart b/bin/growpart
index 595c40b..d4c995b 100755
--- a/bin/growpart
+++ b/bin/growpart
@@ -28,7 +28,6 @@ PART=""
PT_UPDATE=false
DRY_RUN=0
-MBR_CHS=""
MBR_BACKUP=""
GPT_BACKUP=""
_capture=""
@@ -133,7 +132,8 @@ bad_Usage() {
}
mbr_restore() {
- sfdisk --no-reread "${DISK}" ${MBR_CHS} -I "${MBR_BACKUP}"
+ dd if="${MBR_BACKUP}-${DISK#/dev/}-0x00000000.bak" of="${DISK}" bs=1 \
+ conv=notrunc
}
sfdisk_worked_but_blkrrpart_failed() {
@@ -148,34 +148,26 @@ sfdisk_worked_but_blkrrpart_failed() {
mbr_resize() {
RESTORE_HUMAN="${TEMP_D}/recovery"
- MBR_BACKUP="${TEMP_D}/orig.save"
+ MBR_BACKUP="${TEMP_D}/backup"
local change_out=${TEMP_D}/change.out
local dump_out=${TEMP_D}/dump.out
local new_out=${TEMP_D}/new.out
local dump_mod=${TEMP_D}/dump.mod
- local tmp="${TEMP_D}/tmp.out"
- local err="${TEMP_D}/err.out"
- local _devc cyl _w1 heads _w2 sectors _w3 tot dpart
+ local tot dpart
local pt_start pt_size pt_end max_end new_size change_info
- # --show-pt-geometry outputs something like
- # /dev/sda: 164352 cylinders, 4 heads, 32 sectors/track
- rqe sfd_geom sfdisk "${DISK}" --show-pt-geometry >"${tmp}" &&
- read _devc cyl _w1 heads _w2 sectors _w3 <"${tmp}" &&
- MBR_CHS="-C ${cyl} -H ${heads} -S ${sectors}" ||
- fail "failed to get CHS from ${DISK}"
+ tot=$(sfdisk --list "${DISK}" | awk '{ print $(NF-1) ; exit }') ||
+ fail "failed to get total number of sectors from ${DISK}"
- tot=$((${cyl}*${heads}*${sectors}))
+ debug 1 "total number of sectors of ${DISK} is ${tot}"
- debug 1 "geometry is ${MBR_CHS}. total size=${tot}"
- rqe sfd_dump sfdisk ${MBR_CHS} --unit=S --dump "${DISK}" \
+ rqe sfd_dump sfdisk --dump "${DISK}" \
>"${dump_out}" ||
fail "failed to dump sfdisk info for ${DISK}"
-
{
- echo "## sfdisk ${MBR_CHS} --unit=S --dump ${DISK}"
+ echo "## sfdisk --dump ${DISK}"
cat "${dump_out}"
} >"${RESTORE_HUMAN}"
[ $? -eq 0 ] || fail "failed to save sfdisk -d output"
@@ -237,7 +229,7 @@ mbr_resize() {
exit 0
fi
- LANG=C sfdisk --no-reread "${DISK}" ${MBR_CHS} --force \
+ LANG=C sfdisk --no-reread "${DISK}" --force \
-O "${MBR_BACKUP}" <"${new_out}" >"${change_out}" 2>&1
ret=$?
[ $ret -eq 0 ] || RESTORE_FUNC="mbr_restore"
--
2.1.4

View File

@ -19,6 +19,15 @@ in {
'';
};
resetOnStart = mkOption {
type = types.bool;
default = false;
description = ''
Whether to reset the Open vSwitch configuration database to a default
configuration on every start of the systemd <literal>ovsdb.service</literal>.
'';
};
package = mkOption {
type = types.package;
default = pkgs.openvswitch;
@ -75,6 +84,7 @@ in {
mkdir -p ${runDir}
mkdir -p /var/db/openvswitch
chmod +w /var/db/openvswitch
${optionalString cfg.resetOnStart "rm -f /var/db/openvswitch/conf.db"}
if [[ ! -e /var/db/openvswitch/conf.db ]]; then
${cfg.package}/bin/ovsdb-tool create \
"/var/db/openvswitch/conf.db" \
@ -98,6 +108,7 @@ in {
Restart = "always";
RestartSec = 3;
PIDFile = "/var/run/openvswitch/ovsdb.pid";
# Use service type 'forking' to correctly determine when ovsdb-server is ready.
Type = "forking";
};
postStart = ''
@ -118,6 +129,7 @@ in {
--detach
'';
PIDFile = "/var/run/openvswitch/ovs-vswitchd.pid";
# Use service type 'forking' to correctly determine when vswitchd is ready.
Type = "forking";
};
};
@ -147,6 +159,7 @@ in {
unix:/var/run/openvswitch/db.sock
'';
PIDFile = "/var/run/openvswitch/ovs-monitor-ipsec.pid";
# Use service type 'forking' to correctly determine when ovs-monitor-ipsec is ready.
Type = "forking";
};

View File

@ -32,7 +32,8 @@ in
boot.extraModulePackages = [ kernel.virtualboxGuestAdditions ];
boot.kernelModules = [ "vboxsf" ];
boot.supportedFilesystems = [ "vboxsf" ];
boot.initrd.supportedFilesystems = [ "vboxsf" ];
users.extraGroups.vboxsf.gid = config.ids.gids.vboxsf;

View File

@ -11,93 +11,37 @@ in {
options = {
virtualbox = {
baseImageSize = mkOption {
type = types.str;
default = "10G";
type = types.int;
default = 10 * 1024;
description = ''
The size of the VirtualBox base image. The size string should be on
a format the qemu-img command accepts.
The size of the VirtualBox base image in MiB.
'';
};
};
};
config = {
system.build.virtualBoxImage =
pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "virtualbox-image"
{ memSize = 768;
preVM =
''
mkdir $out
diskImage=$out/image
${pkgs.vmTools.qemu}/bin/qemu-img create -f raw $diskImage "${cfg.baseImageSize}"
mv closure xchg/
'';
postVM =
''
echo "creating VirtualBox disk image..."
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi $diskImage $out/disk.vdi
rm $diskImage
'';
buildInputs = [ pkgs.utillinux pkgs.perl ];
exportReferencesGraph =
[ "closure" config.system.build.toplevel ];
system.build.virtualBoxImage = import ../../lib/make-disk-image.nix {
inherit pkgs lib config;
partitioned = true;
diskSize = cfg.baseImageSize;
configFile = pkgs.writeText "configuration.nix"
''
{
imports = [ <nixpkgs/nixos/modules/virtualisation/virtualbox-image.nix> ];
}
''
# Create a single / 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 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)
echo "filling Nix store..."
mkdir -p /mnt/nix/store
set -f
cp -prd $storePaths /mnt/nix/store/
mkdir -p /mnt/etc/nix
echo 'build-users-group = ' > /mnt/etc/nix/nix.conf
# 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
# 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}
# `nixos-rebuild' requires an /etc/NIXOS.
mkdir -p /mnt/etc/nixos
touch /mnt/etc/NIXOS
# `switch-to-configuration' requires a /bin/sh
mkdir -p /mnt/bin
ln -s ${config.system.build.binsh}/bin/sh /mnt/bin/sh
# Generate the GRUB menu.
ln -s vda /dev/sda
chroot /mnt ${config.system.build.toplevel}/bin/switch-to-configuration boot
umount /mnt/proc /mnt/dev /mnt/sys
umount /mnt
''
);
'';
postVM =
''
echo "creating VirtualBox disk image..."
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi $diskImage $out/disk.vdi
rm $diskImage
'';
};
system.build.virtualBoxOVA = pkgs.runCommand "virtualbox-ova"
{ buildInputs = [ pkgs.linuxPackages.virtualbox ];
vmName = "NixOS ${config.system.nixosVersion} (${pkgs.stdenv.system})";
@ -118,17 +62,17 @@ in {
VBoxManage storagectl "$vmName" --name SATA --add sata --portcount 4 --bootable on --hostiocache on
VBoxManage storageattach "$vmName" --storagectl SATA --port 0 --device 0 --type hdd \
--medium ${config.system.build.virtualBoxImage}/disk.vdi
echo "exporting VirtualBox VM..."
mkdir -p $out
VBoxManage export "$vmName" --output "$out/$fileName"
'';
fileSystems."/".device = "/dev/disk/by-label/nixos";
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/sda";
virtualisation.virtualbox.guest.enable = true;
};
}

View File

@ -220,7 +220,7 @@ in rec {
tests.dockerRegistry = hydraJob (import tests/docker-registry.nix { system = "x86_64-linux"; });
tests.etcd = hydraJob (import tests/etcd.nix { system = "x86_64-linux"; });
tests.ec2-nixops = hydraJob (import tests/ec2.nix { system = "x86_64-linux"; }).boot-ec2-nixops;
tests.ec2-config = hydraJob (import tests/ec2.nix { system = "x86_64-linux"; }).boot-ec2-config;
#tests.ec2-config = hydraJob (import tests/ec2.nix { system = "x86_64-linux"; }).boot-ec2-config;
tests.firefox = callTest tests/firefox.nix {};
tests.firewall = callTest tests/firewall.nix {};
tests.fleet = hydraJob (import tests/fleet.nix { system = "x86_64-linux"; });

View File

@ -9,9 +9,18 @@ let
(import ../lib/eval-config.nix {
inherit system;
modules = [
../maintainers/scripts/ec2/amazon-hvm-config.nix
../maintainers/scripts/ec2/amazon-image.nix
../../nixos/modules/testing/test-instrumentation.nix
{ boot.initrd.kernelModules = [ "virtio" "virtio_blk" "virtio_pci" "virtio_ring" ]; }
{ boot.initrd.kernelModules = [ "virtio" "virtio_blk" "virtio_pci" "virtio_ring" ];
ec2.hvm = true;
# Hack to make the partition resizing work in QEMU.
boot.initrd.postDeviceCommands = mkBefore
''
ln -s vda /dev/xvda
ln -s vda1 /dev/xvda1
'';
}
];
}).config.system.build.amazonImage;
@ -34,41 +43,49 @@ let
nodes = {};
testScript =
''
use File::Temp qw/ tempfile /;
my ($fh, $filename) = tempfile();
my $imageDir = ($ENV{'TMPDIR'} // "/tmp") . "/vm-state-machine";
mkdir $imageDir, 0700;
my $diskImage = "$imageDir/machine.qcow2";
system("qemu-img create -f qcow2 -o backing_file=${image}/nixos.img $diskImage") == 0 or die;
system("qemu-img resize $diskImage 10G") == 0 or die;
`qemu-img create -f qcow2 -o backing_file=${image}/nixos.img $filename`;
my $startCommand = "qemu-kvm -m 768 -net nic -net 'user,net=169.254.0.0/16,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
$startCommand .= " -drive file=" . Cwd::abs_path($filename) . ",if=virtio,werror=report";
# Note: we use net=169.0.0.0/8 rather than
# net=169.254.0.0/16 to prevent dhcpcd from getting horribly
# confused. (It would get a DHCP lease in the 169.254.*
# range, which it would then configure and prompty delete
# again when it deletes link-local addresses.) Ideally we'd
# turn off the DHCP server, but qemu does not have an option
# to do that.
my $startCommand = "qemu-kvm -m 768 -net nic -net 'user,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
$startCommand .= " -drive file=$diskImage,if=virtio,werror=report";
$startCommand .= " \$QEMU_OPTS";
my $machine = createMachine({ startCommand => $startCommand });
${script}
'';
};
snakeOilPrivateKey = [
"-----BEGIN EC PRIVATE KEY-----"
"MHcCAQEEIHQf/khLvYrQ8IOika5yqtWvI0oquHlpRLTZiJy5dRJmoAoGCCqGSM49"
"AwEHoUQDQgAEKF0DYGbBwbj06tA3fd/+yP44cvmwmHBWXZCKbS+RQlAKvLXMWkpN"
"r1lwMyJZoSGgBHoUahoYjTh9/sJL7XLJtA=="
"-----END EC PRIVATE KEY-----"
];
snakeOilPrivateKey = ''
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDEPmwZv5dDPrMUaq0dDP+6eBTTe+QNrz14KBEIdhHd1QAAAJDufJ4S7nye
EgAAAAtzc2gtZWQyNTUxOQAAACDEPmwZv5dDPrMUaq0dDP+6eBTTe+QNrz14KBEIdhHd1Q
AAAECgwbDlYATM5/jypuptb0GF/+zWZcJfoVIFBG3LQeRyGsQ+bBm/l0M+sxRqrR0M/7p4
FNN75A2vPXgoEQh2Ed3VAAAADEVDMiB0ZXN0IGtleQE=
-----END OPENSSH PRIVATE KEY-----
'';
snakeOilPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQ+bBm/l0M+sxRqrR0M/7p4FNN75A2vPXgoEQh2Ed3V EC2 test key";
snakeOilPublicKey = pkgs.lib.concatStrings [
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHA"
"yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa"
"9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= snakeoil"
];
in {
boot-ec2-nixops = makeEc2Test {
name = "nixops-userdata";
sshPublicKey = snakeOilPublicKey; # That's right folks! My user's key is also the host key!
userData = ''
SSH_HOST_DSA_KEY_PUB:${snakeOilPublicKey}
SSH_HOST_DSA_KEY:${pkgs.lib.concatStringsSep "|" snakeOilPrivateKey}
SSH_HOST_ED25519_KEY_PUB:${snakeOilPublicKey}
SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey}
'';
script = ''
$machine->start;
@ -80,8 +97,9 @@ in {
# Let's install our client private key
$machine->succeed("mkdir -p ~/.ssh");
${concatMapStrings (s: "$machine->succeed('echo ${s} >> ~/.ssh/id_ecdsa');") snakeOilPrivateKey}
$machine->succeed("chmod 600 ~/.ssh/id_ecdsa");
$machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519");
$machine->succeed("chmod 600 ~/.ssh/id_ed25519");
# We haven't configured the host key yet, so this should still fail
$machine->fail("ssh -o BatchMode=yes localhost exit");
@ -90,7 +108,16 @@ in {
$machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts");
$machine->succeed("ssh -o BatchMode=yes localhost exit");
# Test whether the root disk was resized.
my $blocks = $machine->succeed("stat -c %b -f /");
my $bsize = $machine->succeed("stat -c %S -f /");
my $size = $blocks * $bsize;
die "wrong free space $size" if $size < 9.7 * 1024 * 1024 * 1024 || $size > 10 * 1024 * 1024 * 1024;
# Just to make sure resizing is idempotent.
$machine->shutdown;
$machine->start;
$machine->waitForFile("/root/user-data");
'';
};

View File

@ -28,7 +28,8 @@ import ./make-test.nix ({ pkgs, ...} : {
$machine->succeed("su - alice -c 'DISPLAY=:0.0 gnome-terminal &'");
$machine->waitForWindow(qr/Terminal/);
$machine->sleep(20);
$machine->mustSucceed("timeout 60 bash -c 'journalctl -f|grep -m 1 \"GNOME Shell started\"'");
$machine->sleep(10);
$machine->screenshot("screen");
'';
})

View File

@ -2,4 +2,4 @@ f: { system ? builtins.currentSystem, ... } @ args:
with import ../lib/testing.nix { inherit system; };
makeTest (if builtins.isFunction f then f (args // { inherit pkgs; }) else f)
makeTest (if builtins.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f)

View File

@ -141,6 +141,7 @@ import ./make-test.nix ({ pkgs, ... }: with pkgs.lib; let
vmFlags = mkFlags ([
"--uart1 0x3F8 4"
"--uartmode1 client /run/virtualbox-log-${name}.sock"
"--memory 768"
] ++ (attrs.vmFlags or []));
controllerFlags = mkFlags [
@ -324,7 +325,7 @@ in {
mkVMConf = name: val: val.machine // { key = "${name}-config"; };
vmConfigs = mapAttrsToList mkVMConf vboxVMs;
in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
virtualisation.memorySize = 1024;
virtualisation.memorySize = 2048;
virtualisation.virtualbox.host.enable = true;
users.extraUsers.alice.extraGroups = let
inherit (config.virtualisation.virtualbox.host) enableHardening;
@ -389,6 +390,21 @@ in {
destroyVM_simple;
sub removeUUIDs {
return join("\n", grep { $_ !~ /^UUID:/ } split(/\n/, $_[0]))."\n";
}
subtest "host-usb-permissions", sub {
my $userUSB = removeUUIDs vbm("list usbhost");
print STDERR $userUSB;
my $rootUSB = removeUUIDs $machine->succeed("VBoxManage list usbhost");
print STDERR $rootUSB;
die "USB host devices differ for root and normal user"
if $userUSB ne $rootUSB;
die "No USB host devices found" if $userUSB =~ /<none>/;
};
subtest "systemd-detect-virt", sub {
createVM_detectvirt;
vbm("startvm detectvirt");
@ -397,6 +413,7 @@ in {
shutdownVM_detectvirt;
my $result = $machine->succeed("cat '$detectvirt_sharepath/result'");
chomp $result;
destroyVM_detectvirt;
die "systemd-detect-virt returned \"$result\" instead of \"oracle\""
if $result ne "oracle";
};
@ -407,11 +424,10 @@ in {
vbm("startvm test1");
waitForStartup_test1;
waitForVMBoot_test1;
vbm("startvm test2");
waitForStartup_test2;
waitForVMBoot_test1;
waitForVMBoot_test2;
$machine->screenshot("net_booted");

View File

@ -1,7 +1,8 @@
{ stdenv, fetchurl, lib, qtscriptgenerator, perl, gettext, curl
, libxml2, mysql, taglib, taglib_extras, loudmouth , kdelibs
, qca2, libmtp, liblastfm, libgpod, pkgconfig, automoc4, phonon
, strigi, soprano, qjson, ffmpeg, libofa, nepomuk_core ? null }:
{ stdenv, fetchurl, lib, automoc4, cmake, perl, pkgconfig
, qtscriptgenerator, gettext, curl , libxml2, mysql, taglib
, taglib_extras, loudmouth , kdelibs , qca2, libmtp, liblastfm, libgpod
, phonon , strigi, soprano, qjson, ffmpeg, libofa, nepomuk_core ? null
}:
stdenv.mkDerivation rec {
name = "${pname}-${version}";
@ -16,9 +17,13 @@ stdenv.mkDerivation rec {
QT_PLUGIN_PATH="${qtscriptgenerator}/lib/qt4/plugins";
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 ];
nativeBuildInputs = [ automoc4 cmake perl pkgconfig ];
buildInputs = [
qtscriptgenerator stdenv.cc.libc gettext curl libxml2 mysql.lib
taglib taglib_extras loudmouth kdelibs phonon strigi soprano qca2
libmtp liblastfm libgpod qjson ffmpeg libofa nepomuk_core
];
cmakeFlags = "-DKDE4_BUILD_TESTS=OFF";

View File

@ -1,5 +1,5 @@
{ stdenv, fetchurl, pkgconfig, glib, gtk3, libmowgli, libmcs
, gettext, dbus_glib, libxml2, libmad, xlibs, alsaLib, libogg
, gettext, dbus_glib, libxml2, libmad, xorg, alsaLib, libogg
, libvorbis, libcdio, libcddb, flac, ffmpeg, makeWrapper
, mpg123, neon, faad2
}:
@ -21,7 +21,7 @@ stdenv.mkDerivation {
buildInputs =
[ gettext pkgconfig glib gtk3 libmowgli libmcs libxml2 dbus_glib
libmad xlibs.libXcomposite libogg libvorbis flac alsaLib libcdio
libmad xorg.libXcomposite libogg libvorbis flac alsaLib libcdio
libcddb ffmpeg makeWrapper mpg123 neon faad2
];

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, alsaLib, libjack2, pkgconfig, libpulseaudio, xlibs }:
{ stdenv, fetchurl, alsaLib, libjack2, pkgconfig, libpulseaudio, xorg }:
stdenv.mkDerivation rec {
name = "bristol-${version}";
@ -10,8 +10,8 @@ stdenv.mkDerivation rec {
};
buildInputs = [
alsaLib libjack2 pkgconfig libpulseaudio xlibs.libX11 xlibs.libXext
xlibs.xproto
alsaLib libjack2 pkgconfig libpulseaudio xorg.libX11 xorg.libXext
xorg.xproto
];
preInstall = ''

View File

@ -0,0 +1,20 @@
{ stdenv, fetchurl, ffmpeg, sox }:
stdenv.mkDerivation rec {
name = "bs1770gain-${version}";
version = "0.4.7";
src = fetchurl {
url = "mirror://sourceforge/bs1770gain/${name}.tar.gz";
sha256 = "0dnypm7k4axc693g0z73n2mvycbzgc4lnj2am64xjzyg37my4qzz";
};
buildInputs = [ ffmpeg sox ];
meta = {
description = "A audio/video loudness scanner implementing ITU-R BS.1770";
license = stdenv.lib.licenses.gpl2Plus;
homepage = "http://bs1770gain.sourceforge.net/";
platforms = stdenv.lib.platforms.all;
};
}

View File

@ -1,6 +1,6 @@
{ stdenv, fetchurl, cmake
, withQt4 ? false, qt4
, withQt5 ? true, qt5
, withQt5 ? true, qtbase, qtsvg, qttools
# 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.
@ -57,7 +57,7 @@ stdenv.mkDerivation rec {
buildInputs =
[ cmake ]
++ stdenv.lib.optional withQt4 qt4
++ stdenv.lib.optionals withQt5 (with qt5; [ base svg tools ])
++ stdenv.lib.optionals withQt5 [ qtbase qtsvg qttools ]
++ stdenv.lib.optional withKDE4 kde4.kdelibs
++ stdenv.lib.optionals withTaglib [ taglib taglib_extras ]
++ stdenv.lib.optionals withReplaygain [ ffmpeg speex mpg123 ]
@ -91,6 +91,10 @@ stdenv.mkDerivation rec {
"-DENABLE_UDISKS2=ON"
];
postInstall = ''
wrapQtProgram "$out/bin/cantata"
'';
meta = with stdenv.lib; {
homepage = http://code.google.com/p/cantata/;
description = "A graphical client for MPD";

View File

@ -1,4 +1,4 @@
{ stdenv, fetchFromGitHub, fftw, libsndfile, qt5 }:
{ stdenv, fetchFromGitHub, fftw, libsndfile, qtbase, qtmultimedia }:
let
@ -39,7 +39,7 @@ in stdenv.mkDerivation {
owner = "gillesdegottex";
};
buildInputs = [ fftw libsndfile qt5.base qt5.multimedia ];
buildInputs = [ fftw libsndfile qtbase qtmultimedia ];
postPatch = ''
substituteInPlace dfasma.pro --replace '$$DFASMAVERSIONGITPRO' '${version}'
@ -53,6 +53,10 @@ in stdenv.mkDerivation {
enableParallelBuilding = true;
postInstall = ''
wrapQtProgram "$out/bin/dfasma"
'';
meta = with stdenv.lib; {
inherit version;
description = "Analyse and compare audio files in time and frequency";

View File

@ -1,5 +1,5 @@
{ stdenv, fetchgit, alsaLib, fftwSinglePrec, freetype, libjack2
, libxslt, lv2, pkgconfig, premake3, xlibs, ladspa-sdk }:
, libxslt, lv2, pkgconfig, premake3, xorg, ladspa-sdk }:
stdenv.mkDerivation rec {
name = "distrho-ports-git-2015-07-18";
@ -16,8 +16,8 @@ stdenv.mkDerivation rec {
buildInputs = [
alsaLib fftwSinglePrec freetype libjack2 pkgconfig premake3
xlibs.libX11 xlibs.libXcomposite xlibs.libXcursor xlibs.libXext
xlibs.libXinerama xlibs.libXrender ladspa-sdk
xorg.libX11 xorg.libXcomposite xorg.libXcursor xorg.libXext
xorg.libXinerama xorg.libXrender ladspa-sdk
];
buildPhase = ''

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, cmake, fftw, gtkmm, libxcb, lv2, pkgconfig, xlibs }:
{ stdenv, fetchurl, cmake, fftw, gtkmm, libxcb, lv2, pkgconfig, xorg }:
stdenv.mkDerivation rec {
name = "eq10q-2-${version}";
version = "beta7.1";
@ -7,7 +7,7 @@ stdenv.mkDerivation rec {
sha256 = "1jmrcx4jlx8kgsy5n4jcxa6qkjqvx7d8l2p7dsmw4hj20s39lgyi";
};
buildInputs = [ cmake fftw gtkmm libxcb lv2 pkgconfig xlibs.libpthreadstubs xlibs.libXdmcp xlibs.libxshmfence ];
buildInputs = [ cmake fftw gtkmm libxcb lv2 pkgconfig xorg.libpthreadstubs xorg.libXdmcp xorg.libxshmfence ];
installFlags = ''
DESTDIR=$(out)

View File

@ -1,4 +1,4 @@
{ stdenv, fetchFromGitHub, fftw, freeglut, qt5
{ stdenv, fetchFromGitHub, fftw, freeglut, qtbase, qtmultimedia
, alsaSupport ? true, alsaLib ? null
, jackSupport ? false, libjack2 ? null
, portaudioSupport ? false, portaudio ? null }:
@ -18,10 +18,10 @@ stdenv.mkDerivation {
owner = "gillesdegottex";
};
buildInputs = [ fftw freeglut qt5.base qt5.multimedia ]
++ stdenv.lib.optional alsaSupport [ alsaLib ]
++ stdenv.lib.optional jackSupport [ libjack2 ]
++ stdenv.lib.optional portaudioSupport [ portaudio ];
buildInputs = [ fftw freeglut qtbase qtmultimedia ]
++ stdenv.lib.optionals alsaSupport [ alsaLib ]
++ stdenv.lib.optionals jackSupport [ libjack2 ]
++ stdenv.lib.optionals portaudioSupport [ portaudio ];
configurePhase = ''
mkdir build

View File

@ -1,12 +1,12 @@
{ stdenv, fetchurl, readline, patchelf, ncurses, qt48, libidn, expat, flac
, libvorbis }:
assert stdenv.system == "x86_64-linux" || stdenv.system == "1686-linux";
assert stdenv.system == "x86_64-linux" || stdenv.system == "i686-linux";
let
archUrl = name: arch: "http://dl.google.com/linux/musicmanager/deb/pool/main/g/google-musicmanager-beta/${name}_${arch}.deb";
in
stdenv.mkDerivation rec {
version = "beta_1.0.182.3607-r0"; # friendly to nix-env version sorting algo
version = "beta_1.0.221.5230-r0"; # friendly to nix-env version sorting algo
product = "google-musicmanager";
name = "${product}-${version}";
@ -18,11 +18,11 @@ stdenv.mkDerivation rec {
src = if stdenv.system == "x86_64-linux"
then fetchurl {
url = archUrl name "amd64";
sha256 = "141x986haxg3r72ggh8prz0qg298jkad1ys8sdvsac92p4adcqx4";
sha256 = "1h0ssbz6y9xi2szalgb5wcxi8m1ylg4qf2za6zgvi908hpan7q37";
}
else fetchurl {
url = archUrl name "i386";
sha256 = "076iaa7pxhj8b1hlg5ah9jfm4qgzgjc9ivvg2l18wp045gnycv1l";
sha256 = "0q8cnzx7s25bpqlbp40d43mwd6m8kvhvdifkqlgc9phpydnqpd1i";
};
unpackPhase = ''

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, alsaLib, libclthreads, libclxclient, libX11, libXft, libXrender, fftwFloat, freetype, fontconfig, libjack2, xlibs, zita-alsa-pcmi }:
{ stdenv, fetchurl, alsaLib, libclthreads, libclxclient, libX11, libXft, libXrender, fftwFloat, freetype, fontconfig, libjack2, xorg, zita-alsa-pcmi }:
stdenv.mkDerivation rec {
name = "jaaa-${version}";

View File

@ -1,4 +1,4 @@
{ stdenv, fetchFromGitHub, libav_0_8, libkeyfinder, qt5, taglib }:
{ stdenv, fetchFromGitHub, libav_0_8, libkeyfinder, qtbase, qtxmlpatterns, taglib }:
let version = "2.00"; in
stdenv.mkDerivation {
@ -30,7 +30,7 @@ stdenv.mkDerivation {
};
# TODO: upgrade libav when "Audio sample format conversion failed" is fixed
buildInputs = [ libav_0_8 libkeyfinder qt5.base qt5.xmlpatterns taglib ];
buildInputs = [ libav_0_8 libkeyfinder qtbase qtxmlpatterns taglib ];
postPatch = ''
substituteInPlace is_KeyFinder.pro \

View File

@ -1,6 +1,7 @@
{ stdenv, fetchurl, cmake, pkgconfig
, alsaLib, freetype, libjack2, lame, libogg, libpulseaudio, libsndfile, libvorbis
, portaudio, qt5 #, tesseract
, portaudio, qtbase, qtdeclarative, qtenginio, qtscript, qtsvg, qttools
, qtwebkit, qtxmlpatterns
}:
stdenv.mkDerivation rec {
@ -36,8 +37,8 @@ stdenv.mkDerivation rec {
buildInputs = [
alsaLib libjack2 freetype lame libogg libpulseaudio libsndfile libvorbis
portaudio qt5.base qt5.declarative qt5.enginio qt5.script qt5.svg qt5.tools
qt5.webkit qt5.xmlpatterns #tesseract
portaudio qtbase qtdeclarative qtenginio qtscript qtsvg qttools
qtwebkit qtxmlpatterns #tesseract
];
meta = with stdenv.lib; {

View File

@ -15,11 +15,11 @@ assert taglibSupport -> (taglib != null);
with stdenv.lib;
stdenv.mkDerivation rec {
name = "ncmpcpp-${version}";
version = "0.6.5";
version = "0.6.7";
src = fetchurl {
url = "http://ncmpcpp.rybczak.net/stable/${name}.tar.bz2";
sha256 = "1zfidkskmiqx1wfykinmr639lhd90s7b0rks6vaci4n56ml8y4ji";
sha256 = "0yr1ib14qkgbsv839anpzkfbwkm6gg8wv4bf98ar7q5l2p2pv008";
};
configureFlags = [ "BOOST_LIB_SUFFIX=" ]

View File

@ -1,40 +1,34 @@
# Based on Richard Wallace's post here: http://comments.gmane.org/gmane.linux.distributions.nixos/14734
{ fetchFromGitHub, stdenv, pythonPackages, gtk3, gobjectIntrospection, libnotify
, gst_all_1, wrapGAppsHook }:
{ fetchurl, stdenv, pythonPackages, gtk3, libnotify, gst_all_1 }:
pythonPackages.buildPythonPackage rec {
name = "pithos-${version}";
version = "1.0.1";
version = "1.1.1";
src = fetchurl {
url = "https://github.com/pithos/pithos/archive/${version}.tar.gz";
sha256 = "67b83927d5111067aefbf034d23880f96b1a2d300464e8491efa80e97e67f50f";
namePrefix = "";
src = fetchFromGitHub {
owner = "pithos";
repo = "pithos";
rev = version;
sha256 = "0373z7g1wd3g1xl8m4ipx5n2ka67a2wcn387nyk8yvgdikm14jm3";
};
postPatch = ''
substituteInPlace setup.py --replace "/usr/share" "$out/share"
'';
buildInputs = with gst_all_1; [ gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly gst-plugins-bad libnotify ];
buildInputs = [ wrapGAppsHook ];
pythonPath = with pythonPackages; [ pygobject3 dbus pylast ];
propogatedBuildInputs = pythonPath;
postInstall = ''
wrapProgram "$out/bin/pithos" --prefix GST_PLUGIN_SYSTEM_PATH_1_0 ":" "$GST_PLUGIN_SYSTEM_PATH_1_0"
'';
propagatedBuildInputs =
[ gtk3 gobjectIntrospection libnotify ] ++
(with gst_all_1; [ gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly gst-plugins-bad ]) ++
(with pythonPackages; [ pygobject3 pylast ]);
meta = with stdenv.lib; {
description = "Pandora player";
longDescription = ''
Pandora Internet Radio player for GNOME
'';
homepage = http://pithos.github.io/ ;
description = "Pandora Internet Radio player for GNOME";
homepage = https://pithos.github.io/;
license = licenses.gpl3;
maintainers = with maintainers; [ obadz ];
maintainers = with maintainers; [ obadz jgeerds ];
};
}

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, cmake, qt4, pkgconfig, x11
{ stdenv, fetchurl, cmake, qt4, pkgconfig, xlibsWrapper
# transports
, curl, libmms
# input plugins
@ -37,7 +37,7 @@ stdenv.mkDerivation rec {
buildInputs =
[ # basic requirements
cmake qt4 pkgconfig x11
cmake qt4 pkgconfig xlibsWrapper
# transports
curl libmms
# input plugins

View File

@ -1,5 +1,5 @@
{ stdenv, pkgs, fetchFromGitHub,
automake, pkgconfig, lv2, fftw, cmake, xlibs, libjack2, libsamplerate, libsndfile
automake, pkgconfig, lv2, fftw, cmake, xorg, libjack2, libsamplerate, libsndfile
}:
stdenv.mkDerivation rec {
@ -13,7 +13,7 @@ stdenv.mkDerivation rec {
sha256 = "0kr3rvq7n1bh47qryyarcpiibms601qd8l1vypmm61969l4d4bn8";
};
buildInputs = with xlibs; [ automake pkgconfig lv2 fftw cmake libXpm libjack2 libsamplerate libsndfile libXft ];
buildInputs = with xorg; [ automake pkgconfig lv2 fftw cmake libXpm libjack2 libsamplerate libsndfile libXft ];
meta = {
description = "Rakarrak effects ported to LV2";

View File

@ -2,7 +2,7 @@
{ stdenv, fetchurl, alsaLib, bzip2, fftw, libjack2, libX11, liblo
, libmad, libogg, librdf, librdf_raptor, librdf_rasqal, libsamplerate
, libsndfile, pkgconfig, libpulseaudio, qt5, redland
, libsndfile, pkgconfig, libpulseaudio, qtbase, redland
, rubberband, serd, sord, vampSDK, fftwFloat
}:
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
};
buildInputs =
[ libsndfile qt5.base fftw fftwFloat bzip2 librdf rubberband
[ libsndfile qtbase fftw fftwFloat bzip2 librdf rubberband
libsamplerate vampSDK alsaLib librdf_raptor librdf_rasqal redland
serd
sord
@ -43,6 +43,7 @@ stdenv.mkDerivation rec {
mkdir -p $out/{bin,share/sonic-visualiser}
cp sonic-visualiser $out/bin/
cp -r samples $out/share/sonic-visualiser/
wrapQtProgram "$out/bin/sonic-visualiser"
'';
meta = with stdenv.lib; {

View File

@ -3,8 +3,8 @@
, makeWrapper }:
let
major = "3.15";
minor = "92";
major = "3.16";
minor = "1";
GST_PLUGIN_PATH = stdenv.lib.makeSearchPath "lib/gstreamer-1.0" [
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
@ -17,7 +17,7 @@ in stdenv.mkDerivation rec {
src = fetchurl {
url = "http://download.gnome.org/sources/sound-juicer/${major}/${name}.tar.xz";
sha256 = "b1420f267a4c553f6ca242d3b6082b60682c3d7b431ac3c979bd1ccfbf2687dd";
sha256 = "0mx6n901vb97hsv0cwaafjffj75s1kcp8jsqay90dy3099849dyz";
};
buildInputs = [ pkgconfig gtk3 intltool itstool libxml2 brasero libcanberra_gtk3

View File

@ -1,4 +1,4 @@
{ fetchurl, stdenv, dpkg, xlibs, qt4, alsaLib, makeWrapper, openssl, freetype
{ fetchurl, stdenv, dpkg, xorg, qt4, alsaLib, makeWrapper, openssl, freetype
, glib, pango, cairo, atk, gdk_pixbuf, gtk, cups, nspr, nss, libpng, GConf
, libgcrypt, chromium, udev, fontconfig
, dbus, expat }:
@ -28,16 +28,16 @@ let
qt4
stdenv.cc.cc
udev
xlibs.libX11
xlibs.libXcomposite
xlibs.libXdamage
xlibs.libXext
xlibs.libXfixes
xlibs.libXi
xlibs.libXrandr
xlibs.libXrender
xlibs.libXrender
xlibs.libXScrnSaver
xorg.libX11
xorg.libXcomposite
xorg.libXdamage
xorg.libXext
xorg.libXfixes
xorg.libXi
xorg.libXrandr
xorg.libXrender
xorg.libXrender
xorg.libXScrnSaver
];
in

View File

@ -1,6 +1,6 @@
{ stdenv, fetchurl, makeWrapper
, expat, fftwFloat, fontconfig, freetype, libjack2, jack2Full, libclthreads, libclxclient
, libsndfile, libxcb, xlibs
, libsndfile, libxcb, xorg
}:
stdenv.mkDerivation rec {
@ -16,7 +16,7 @@ stdenv.mkDerivation rec {
buildInputs = [
expat libjack2 libclthreads libclxclient fftwFloat fontconfig libsndfile freetype
libxcb xlibs.libX11 xlibs.libXau xlibs.libXdmcp xlibs.libXft xlibs.libXrender
libxcb xorg.libX11 xorg.libXau xorg.libXdmcp xorg.libXft xorg.libXrender
];
makeFlags = [

View File

@ -15,11 +15,11 @@ let
quazipQt4 = quazip.override { qt = qt4; };
in stdenv.mkDerivation rec {
name = "tomahawk-${version}";
version = "0.8.3";
version = "0.8.4";
src = fetchurl {
url = "http://download.tomahawk-player.org/${name}.tar.bz2";
sha256 = "0kjzkq21g3jl1lvadsm7gf0zvpbsv208kqf76wg2hnbm4k1a02wj";
sha256 = "0j84h36wkjfjbsd7ybyji7rcc9wpjdbl0f1xdcc1g7h0nz34pc0g";
};
cmakeFlags = [

View File

@ -1,6 +1,12 @@
{stdenv, fetchurl, libogg, libvorbis, libao, pkgconfig, curl, glibc
, speex, flac}:
{ stdenv, fetchurl, fetchzip, libogg, libvorbis, libao, pkgconfig, curl
, speex, flac }:
let
debPatch = fetchzip {
url = "mirror://debian/pool/main/v/vorbis-tools/vorbis-tools_1.4.0-6.debian.tar.xz";
sha256 = "1xmmpdvxyr84lazlg23c6ck5ic97ga2rkiqabb1d98ix2zdzyqz5";
};
in
stdenv.mkDerivation {
name = "vorbis-tools-1.4.0";
src = fetchurl {
@ -8,14 +14,23 @@ stdenv.mkDerivation {
sha256 = "1g12bnh5ah08v529y72kfdz5lhvy75iaz7f9jskyby23m9dkk2d3";
};
buildInputs = [ libogg libvorbis libao pkgconfig curl speex glibc flac ];
postPatch = ''
for patch in $(ls "${debPatch}"/patches/*.{diff,patch} | grep -v debian_subdir)
do patch -p1 < "$patch"
done
'';
meta = {
buildInputs = [ libogg libvorbis libao pkgconfig curl speex flac ];
meta = with stdenv.lib; {
description = "Extra tools for Ogg-Vorbis audio codec";
longDescription = ''
A set of command-line tools to manipulate Ogg Vorbis audio
files, notably the `ogg123' player and the `oggenc' encoder.
'';
homepage = http://xiph.org/vorbis/;
license = stdenv.lib.licenses.gpl2;
license = licenses.gpl2;
platforms = platforms.all;
};
}

View File

@ -6,11 +6,11 @@ assert stdenv ? glibc;
stdenv.mkDerivation rec {
name = "yoshimi-${version}";
version = "1.3.5.1";
version = "1.3.5.2";
src = fetchurl {
url = "mirror://sourceforge/yoshimi/${name}.tar.bz2";
sha256 = "1c7049pnvadxndk1rbja77kyr0rwnqca2546pxjnxksg923s5l8n";
sha256 = "001xvwknsm1sv5lvwz7f6dgf57b8djbpwbyk2gfxjy9rzl5q53qr";
};
buildInputs = [

View File

@ -1,6 +1,7 @@
{ stdenv, fetchurl, pam, pkgconfig, libxcb, glib, libXdmcp, itstool, libxml2
, intltool, x11, libxklavier, libgcrypt, libaudit
, qt4 ? null, qt5 ? null
, intltool, xlibsWrapper, libxklavier, libgcrypt, libaudit
, qt4 ? null
, withQt5 ? false, qtbase
}:
let
@ -20,14 +21,14 @@ stdenv.mkDerivation rec {
buildInputs = [
pkgconfig pam libxcb glib libXdmcp itstool libxml2 intltool libxklavier libgcrypt
qt4 libaudit
] ++ stdenv.lib.optional (qt5 != null) qt5.base;
] ++ stdenv.lib.optional withQt5 qtbase;
configureFlags = [
"--localstatedir=/var"
"--sysconfdir=/etc"
"--disable-tests"
] ++ stdenv.lib.optional (qt4 != null) "--enable-liblightdm-qt"
++ stdenv.lib.optional ((qt5.base or null) != null) "--enable-liblightdm-qt5";
++ stdenv.lib.optional withQt5 "--enable-liblightdm-qt5";
installFlags = [
"sysconfdir=\${out}/etc"

Some files were not shown because too many files have changed in this diff Show More