Merge branch 'master' into staging

We have zero diff from master ATM.
This commit is contained in:
Vladimír Čunát 2016-03-28 13:38:29 +02:00
commit 9fbde14fe7
964 changed files with 67924 additions and 7201 deletions

View File

@ -1,7 +1,10 @@
###### Things done: ###### Things done:
- [ ] Tested using sandboxing (`nix-build --option build-use-chroot true` or [nix.useChroot](http://nixos.org/nixos/manual/options.html#opt-nix.useChroot) on NixOS) - [ ] Tested using sandboxing (`nix-build --option build-use-chroot true` or [nix.useChroot](http://nixos.org/nixos/manual/options.html#opt-nix.useChroot) on NixOS)
- [ ] Built on platform(s): NixOS / OSX / Linux - Built on platform(s)
- [ ] NixOS
- [ ] OS X
- [ ] Linux
- [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"` - [ ] Tested compilation of all pkgs that depend on this change using `nix-shell -p nox --run "nox-review wip"`
- [ ] Tested execution of all binary files (usually in `./result/bin/`) - [ ] Tested execution of all binary files (usually in `./result/bin/`)
- [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md). - [ ] Fits [CONTRIBUTING.md](https://github.com/NixOS/nixpkgs/blob/master/.github/CONTRIBUTING.md).

View File

@ -6,4 +6,4 @@ if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.
else else
import ./pkgs/top-level/all-packages.nix import ./pkgs/top-level

View File

@ -23,22 +23,8 @@ such as Perl or Haskell. These are described in this chapter.</para>
<xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md --> <xi:include href="idris.xml" /> <!-- generated from ../../pkgs/development/idris-modules/README.md -->
<xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md --> <xi:include href="r.xml" /> <!-- generated from ../../pkgs/development/r-modules/README.md -->
<xi:include href="qt.xml" /> <xi:include href="qt.xml" />
<xi:include href="texlive.xml" />
<!--
<section><title>Haskell</title>
<para>TODO</para>
</section>
<section><title>TeX / LaTeX</title>
<para>* Special support for building TeX documents</para>
</section>
-->
</chapter> </chapter>

View File

@ -12,25 +12,26 @@
<screen> <screen>
<![CDATA[$ cd pkgs/servers/monitoring <![CDATA[$ cd pkgs/servers/monitoring
$ mkdir sensu $ mkdir sensu
$ cd sensu
$ cat > Gemfile $ cat > Gemfile
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'sensu' gem 'sensu'
$ bundler package --path /tmp/vendor/bundle $ nix-shell -p bundler --command "bundler package --path /tmp/vendor/bundle"
$ $(nix-build '<nixpkgs>' -A bundix)/bin/bundix $ $(nix-build '<nixpkgs>' -A bundix)/bin/bundix
$ cat > default.nix $ cat > default.nix
{ lib, bundlerEnv, ruby }: { lib, bundlerEnv, ruby }:
bundlerEnv { bundlerEnv rec {
name = "sensu-0.17.1"; name = "sensu-${version}";
version = (import gemset).sensu.version;
inherit ruby; inherit ruby;
gemfile = ./Gemfile; gemfile = ./Gemfile;
lockfile = ./Gemfile.lock; lockfile = ./Gemfile.lock;
gemset = ./gemset.nix; gemset = ./gemset.nix;
meta = with lib; { meta = with lib; {
description = "A monitoring framework that aims to be simple, malleable, description = "A monitoring framework that aims to be simple, malleable, and scalable";
and scalable.";
homepage = http://sensuapp.org/; homepage = http://sensuapp.org/;
license = with licenses; mit; license = with licenses; mit;
maintainers = with maintainers; [ theuni ]; maintainers = with maintainers; [ theuni ];

View File

@ -0,0 +1,59 @@
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-language-texlive">
<title>TeX Live</title>
<para>Since release 15.09 there is a new TeX Live packaging that lives entirely under attribute <varname>texlive</varname>.</para>
<section><title>User's guide</title>
<itemizedlist>
<listitem><para>
For basic usage just pull <varname>texlive.combined.scheme-basic</varname> for an environment with basic LaTeX support.</para></listitem>
<listitem><para>
It typically won't work to use separately installed packages together.
Instead, you can build a custom set of packages like this:
<programlisting>
texlive.combine {
inherit (texlive) scheme-small collection-langkorean algorithms cm-super;
}
</programlisting>
There are all the schemes, collections and a few thousand packages, as defined upstream (perhaps with tiny differences).
</para></listitem>
<listitem><para>
By default you only get executables and files needed during runtime, and a little documentation for the core packages. To change that, you need to add <varname>pkgFilter</varname> function to <varname>combine</varname>.
<programlisting>
texlive.combine {
# inherit (texlive) whatever-you-want;
pkgFilter = pkg:
pkg.tlType == "run" || pkg.tlType == "bin" || pkg.pname == "cm-super";
# elem tlType [ "run" "bin" "doc" "source" ]
# there are also other attributes: version, name
}
</programlisting>
</para></listitem>
<listitem><para>
You can list packages e.g. by <command>nix-repl</command>.
<programlisting>
$ nix-repl
nix-repl> texlive.collection-&lt;TAB>
</programlisting>
</para></listitem>
</itemizedlist>
</section>
<section><title>Known problems</title>
<itemizedlist>
<listitem><para>
Some tools are still missing, e.g. luajittex;</para></listitem>
<listitem><para>
some apps aren't packaged/tested yet (asymptote, biber, etc.);</para></listitem>
<listitem><para>
feature/bug: when a package is rejected by <varname>pkgFilter</varname>, its dependencies are still propagated;</para></listitem>
<listitem><para>
in case of any bugs or feature requests, file a github issue or better a pull request and /cc @vcunat.</para></listitem>
</itemizedlist>
</section>
</section>

View File

@ -12,9 +12,15 @@ rec {
inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr; inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr;
/* Return an attribute from nested attribute sets. For instance /* Return an attribute from nested attribute sets.
["x" "y"] applied to some set e returns e.x.y, if it exists. The
default value is returned otherwise. */ Example:
x = { a = { b = 3; }; }
attrByPath ["a" "b"] 6 x
=> 3
attrByPath ["z" "z"] 6 x
=> 6
*/
attrByPath = attrPath: default: e: attrByPath = attrPath: default: e:
let attr = head attrPath; let attr = head attrPath;
in in
@ -24,8 +30,15 @@ rec {
else default; else default;
/* Return if an attribute from nested attribute set exists. /* Return if an attribute from nested attribute set exists.
For instance ["x" "y"] applied to some set e returns true, if e.x.y exists. False
is returned otherwise. */ Example:
x = { a = { b = 3; }; }
hasAttrByPath ["a" "b"] x
=> true
hasAttrByPath ["z" "z"] x
=> false
*/
hasAttrByPath = attrPath: e: hasAttrByPath = attrPath: e:
let attr = head attrPath; let attr = head attrPath;
in in
@ -35,14 +48,28 @@ rec {
else false; else false;
/* Return nested attribute set in which an attribute is set. For instance /* Return nested attribute set in which an attribute is set.
["x" "y"] applied with some value v returns `x.y = v;' */
Example:
setAttrByPath ["a" "b"] 3
=> { a = { b = 3; }; }
*/
setAttrByPath = attrPath: value: setAttrByPath = attrPath: value:
if attrPath == [] then value if attrPath == [] then value
else listToAttrs else listToAttrs
[ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ]; [ { name = head attrPath; value = setAttrByPath (tail attrPath) value; } ];
/* Like `getAttrPath' without a default value. If it doesn't find the
path it will throw.
Example:
x = { a = { b = 3; }; }
getAttrFromPath ["a" "b"] x
=> 3
getAttrFromPath ["z" "z"] x
=> error: cannot find attribute `z.z'
*/
getAttrFromPath = attrPath: set: getAttrFromPath = attrPath: set:
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'"; let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
in attrByPath attrPath (abort errorMsg) set; in attrByPath attrPath (abort errorMsg) set;
@ -109,9 +136,11 @@ rec {
) (attrNames set) ) (attrNames set)
); );
/* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list: /* Apply fold functions to values grouped by key.
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
=> { a = [ 2 3 ]; } Example:
foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
=> { a = [ 2 3 ]; }
*/ */
foldAttrs = op: nul: list_of_attrs: foldAttrs = op: nul: list_of_attrs:
fold (n: a: fold (n: a:
@ -147,7 +176,12 @@ rec {
/* Utility function that creates a {name, value} pair as expected by /* Utility function that creates a {name, value} pair as expected by
builtins.listToAttrs. */ builtins.listToAttrs.
Example:
nameValuePair "some" 6
=> { name = "some"; value = 6; }
*/
nameValuePair = name: value: { inherit name value; }; nameValuePair = name: value: { inherit name value; };
@ -248,11 +282,19 @@ rec {
listToAttrs (map (n: nameValuePair n (f n)) names); listToAttrs (map (n: nameValuePair n (f n)) names);
/* Check whether the argument is a derivation. */ /* Check whether the argument is a derivation. Any set with
{ type = "derivation"; } counts as a derivation.
Example:
nixpkgs = import <nixpkgs> {}
isDerivation nixpkgs.ruby
=> true
isDerivation "foobar"
=> false
*/
isDerivation = x: isAttrs x && x ? type && x.type == "derivation"; isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
/* Converts a store path to a fake derivation. */
/* Convert a store path to a fake derivation. */
toDerivation = path: toDerivation = path:
let path' = builtins.storePath path; in let path' = builtins.storePath path; in
{ type = "derivation"; { type = "derivation";
@ -262,32 +304,49 @@ rec {
}; };
/* If the Boolean `cond' is true, return the attribute set `as', /* If `cond' is true, return the attribute set `as',
otherwise an empty attribute set. */ otherwise an empty attribute set.
Example:
optionalAttrs (true) { my = "set"; }
=> { my = "set"; }
optionalAttrs (false) { my = "set"; }
=> { }
*/
optionalAttrs = cond: as: if cond then as else {}; optionalAttrs = cond: as: if cond then as else {};
/* Merge sets of attributes and use the function f to merge attributes /* Merge sets of attributes and use the function f to merge attributes
values. */ values.
Example:
zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
=> { a = ["x" "y"]; }
*/
zipAttrsWithNames = names: f: sets: zipAttrsWithNames = names: f: sets:
listToAttrs (map (name: { listToAttrs (map (name: {
inherit name; inherit name;
value = f name (catAttrs name sets); value = f name (catAttrs name sets);
}) names); }) names);
# implentation note: Common names appear multiple times in the list of /* Implentation note: Common names appear multiple times in the list of
# names, hopefully this does not affect the system because the maximal names, hopefully this does not affect the system because the maximal
# laziness avoid computing twice the same expression and listToAttrs does laziness avoid computing twice the same expression and listToAttrs does
# not care about duplicated attribute names. not care about duplicated attribute names.
Example:
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
=> { a = ["x" "y"]; b = ["z"] }
*/
zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets; zipAttrsWith = f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets;
/* Like `zipAttrsWith' with `(name: values: value)' as the function.
Example:
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
=> { a = ["x" "y"]; b = ["z"] }
*/
zipAttrs = zipAttrsWith (name: values: values); zipAttrs = zipAttrsWith (name: values: values);
/* backward compatibility */
zipWithNames = zipAttrsWithNames;
zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
/* Does the same as the update operator '//' except that attributes are /* Does the same as the update operator '//' except that attributes are
merged until the given pedicate is verified. The predicate should merged until the given pedicate is verified. The predicate should
accept 3 arguments which are the path to reach the attribute, a part of accept 3 arguments which are the path to reach the attribute, a part of
@ -351,6 +410,15 @@ rec {
!(isAttrs lhs && isAttrs rhs) !(isAttrs lhs && isAttrs rhs)
) lhs rhs; ) lhs rhs;
/* Returns true if the pattern is contained in the set. False otherwise.
FIXME(zimbatm): this example doesn't work !!!
Example:
sys = mkSystem { }
matchAttrs { cpu = { bits = 64; }; } sys
=> true
*/
matchAttrs = pattern: attrs: matchAttrs = pattern: attrs:
fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values: fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
let pat = head values; val = head (tail values); in let pat = head values; val = head (tail values); in
@ -359,10 +427,23 @@ rec {
else pat == val else pat == val
) [pattern attrs])); ) [pattern attrs]));
# override only the attributes that are already present in the old set /* Override only the attributes that are already present in the old set
# useful for deep-overriding useful for deep-overriding.
Example:
x = { a = { b = 4; c = 3; }; }
overrideExisting x { a = { b = 6; d = 2; }; }
=> { a = { b = 6; d = 2; }; }
*/
overrideExisting = old: new: overrideExisting = old: new:
old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old)); old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] old.${attr} new)) (attrNames old));
deepSeqAttrs = x: y: deepSeqList (attrValues x) y;
/*** deprecated stuff ***/
deepSeqAttrs = throw "removed 2016-02-29 because unused and broken";
zipWithNames = zipAttrsWithNames;
zip = builtins.trace
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
} }

View File

@ -175,6 +175,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
fullName = "Eclipse Public License 1.0"; fullName = "Eclipse Public License 1.0";
}; };
epson = {
fullName = "Seiko Epson Corporation Software License Agreement for Linux";
url = https://download.ebz.epson.net/dsc/du/02/eula/global/LINUX_EN.html;
free = false;
};
fdl12 = spdx { fdl12 = spdx {
spdxId = "GFDL-1.2"; spdxId = "GFDL-1.2";
fullName = "GNU Free Documentation License v1.2"; fullName = "GNU Free Documentation License v1.2";

View File

@ -6,17 +6,26 @@ rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList; inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
/* Create a list consisting of a single element. `singleton x' is
sometimes more convenient with respect to indentation than `[x]'
when x spans multiple lines.
# Create a list consisting of a single element. `singleton x' is Example:
# sometimes more convenient with respect to indentation than `[x]' singleton "foo"
# when x spans multiple lines. => [ "foo" ]
*/
singleton = x: [x]; singleton = x: [x];
/* "Fold" a binary function `op' between successive elements of
`list' with `nul' as the starting value, i.e., `fold op nul [x_1
x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is
Haskell's foldr).
# "Fold" a binary function `op' between successive elements of Example:
# `list' with `nul' as the starting value, i.e., `fold op nul [x_1 concat = fold (a: b: a + b) "z"
# x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is concat [ "a" "b" "c" ]
# Haskell's foldr). => "abcnul"
*/
fold = op: nul: list: fold = op: nul: list:
let let
len = length list; len = length list;
@ -26,8 +35,14 @@ rec {
else op (elemAt list n) (fold' (n + 1)); else op (elemAt list n) (fold' (n + 1));
in fold' 0; in fold' 0;
# Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul /* Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul
# x_1) x_2) ... x_n)'. x_1) x_2) ... x_n)'.
Example:
lconcat = foldl (a: b: a + b) "z"
lconcat [ "a" "b" "c" ]
=> "zabc"
*/
foldl = op: nul: list: foldl = op: nul: list:
let let
len = length list; len = length list;
@ -37,13 +52,22 @@ rec {
else op (foldl' (n - 1)) (elemAt list n); else op (foldl' (n - 1)) (elemAt list n);
in foldl' (length list - 1); in foldl' (length list - 1);
/* Strict version of foldl.
# Strict version of foldl. The difference is that evaluation is forced upon access. Usually used
with small whole results (in contract with lazily-generated list or large
lists where only a part is consumed.)
*/
foldl' = builtins.foldl' or foldl; foldl' = builtins.foldl' or foldl;
/* Map with index
# Map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] == FIXME(zimbatm): why does this start to count at 1?
# ["a-1" "b-2"]'. FIXME: why does this start to count at 1?
Example:
imap (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-1" "b-2" ]
*/
imap = imap =
if builtins ? genList then if builtins ? genList then
f: list: genList (n: f (n + 1) (elemAt list n)) (length list) f: list: genList (n: f (n + 1) (elemAt list n)) (length list)
@ -57,73 +81,141 @@ rec {
else [ (f (n + 1) (elemAt list n)) ] ++ imap' (n + 1); else [ (f (n + 1) (elemAt list n)) ] ++ imap' (n + 1);
in imap' 0; in imap' 0;
/* Map and concatenate the result.
# Map and concatenate the result. Example:
concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ]
*/
concatMap = f: list: concatLists (map f list); concatMap = f: list: concatLists (map f list);
/* Flatten the argument into a single list; that is, nested lists are
spliced into the top-level lists.
# Flatten the argument into a single list; that is, nested lists are Example:
# spliced into the top-level lists. E.g., `flatten [1 [2 [3] 4] 5] flatten [1 [2 [3] 4] 5]
# == [1 2 3 4 5]' and `flatten 1 == [1]'. => [1 2 3 4 5]
flatten 1
=> [1]
*/
flatten = x: flatten = x:
if isList x if isList x
then foldl' (x: y: x ++ (flatten y)) [] x then foldl' (x: y: x ++ (flatten y)) [] x
else [x]; else [x];
/* Remove elements equal to 'e' from a list. Useful for buildInputs.
# Remove elements equal to 'e' from a list. Useful for buildInputs. Example:
remove 3 [ 1 3 4 3 ]
=> [ 1 4 ]
*/
remove = e: filter (x: x != e); remove = e: filter (x: x != e);
/* Find the sole element in the list matching the specified
predicate, returns `default' if no such element exists, or
`multiple' if there are multiple matching elements.
# Find the sole element in the list matching the specified Example:
# predicate, returns `default' if no such element exists, or findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
# `multiple' if there are multiple matching elements. => "multiple"
findSingle (x: x == 3) "none" "multiple" [ 1 3 ]
=> 3
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
=> "none"
*/
findSingle = pred: default: multiple: list: findSingle = pred: default: multiple: list:
let found = filter pred list; len = length found; let found = filter pred list; len = length found;
in if len == 0 then default in if len == 0 then default
else if len != 1 then multiple else if len != 1 then multiple
else head found; else head found;
/* Find the first element in the list matching the specified
predicate or returns `default' if no such element exists.
# Find the first element in the list matching the specified Example:
# predicate or returns `default' if no such element exists. findFirst (x: x > 3) 7 [ 1 6 4 ]
=> 6
findFirst (x: x > 9) 7 [ 1 6 4 ]
=> 7
*/
findFirst = pred: default: list: findFirst = pred: default: list:
let found = filter pred list; let found = filter pred list;
in if found == [] then default else head found; in if found == [] then default else head found;
/* Return true iff function `pred' returns true for at least element
of `list'.
# Return true iff function `pred' returns true for at least element Example:
# of `list'. any isString [ 1 "a" { } ]
=> true
any isString [ 1 { } ]
=> false
*/
any = builtins.any or (pred: fold (x: y: if pred x then true else y) false); any = builtins.any or (pred: fold (x: y: if pred x then true else y) false);
/* Return true iff function `pred' returns true for all elements of
`list'.
# Return true iff function `pred' returns true for all elements of Example:
# `list'. all (x: x < 3) [ 1 2 ]
=> true
all (x: x < 3) [ 1 2 3 ]
=> false
*/
all = builtins.all or (pred: fold (x: y: if pred x then y else false) true); all = builtins.all or (pred: fold (x: y: if pred x then y else false) true);
/* Count how many times function `pred' returns true for the elements
of `list'.
# Count how many times function `pred' returns true for the elements Example:
# of `list'. count (x: x == 3) [ 3 2 3 4 6 ]
=> 2
*/
count = pred: foldl' (c: x: if pred x then c + 1 else c) 0; count = pred: foldl' (c: x: if pred x then c + 1 else c) 0;
/* Return a singleton list or an empty list, depending on a boolean
value. Useful when building lists with optional elements
(e.g. `++ optional (system == "i686-linux") flashplayer').
# Return a singleton list or an empty list, depending on a boolean Example:
# value. Useful when building lists with optional elements optional true "foo"
# (e.g. `++ optional (system == "i686-linux") flashplayer'). => [ "foo" ]
optional false "foo"
=> [ ]
*/
optional = cond: elem: if cond then [elem] else []; optional = cond: elem: if cond then [elem] else [];
/* Return a list or an empty list, dependening on a boolean value.
# Return a list or an empty list, dependening on a boolean value. Example:
optionals true [ 2 3 ]
=> [ 2 3 ]
optionals false [ 2 3 ]
=> [ ]
*/
optionals = cond: elems: if cond then elems else []; optionals = cond: elems: if cond then elems else [];
# If argument is a list, return it; else, wrap it in a singleton /* If argument is a list, return it; else, wrap it in a singleton
# list. If you're using this, you should almost certainly list. If you're using this, you should almost certainly
# reconsider if there isn't a more "well-typed" approach. reconsider if there isn't a more "well-typed" approach.
Example:
toList [ 1 2 ]
=> [ 1 2 ]
toList "hi"
=> [ "hi "]
*/
toList = x: if isList x then x else [x]; toList = x: if isList x then x else [x];
/* Return a list of integers from `first' up to and including `last'.
# Return a list of integers from `first' up to and including `last'. Example:
range 2 4
=> [ 2 3 4 ]
range 3 2
=> [ ]
*/
range = range =
if builtins ? genList then if builtins ? genList then
first: last: first: last:
@ -136,9 +228,13 @@ rec {
then [] then []
else [first] ++ range (first + 1) last; else [first] ++ range (first + 1) last;
/* Splits the elements of a list in two lists, `right' and
`wrong', depending on the evaluation of a predicate.
# Partition the elements of a list in two lists, `right' and Example:
# `wrong', depending on the evaluation of a predicate. partition (x: x > 2) [ 5 1 2 3 4 ]
=> { right = [ 5 3 4 ]; wrong = [ 1 2 ]; }
*/
partition = pred: partition = pred:
fold (h: t: fold (h: t:
if pred h if pred h
@ -146,7 +242,14 @@ rec {
else { right = t.right; wrong = [h] ++ t.wrong; } else { right = t.right; wrong = [h] ++ t.wrong; }
) { right = []; wrong = []; }; ) { right = []; wrong = []; };
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest. How both lists are merged is defined
by the first argument.
Example:
zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
=> ["he" "lo"]
*/
zipListsWith = zipListsWith =
if builtins ? genList then if builtins ? genList then
f: fst: snd: genList (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd)) f: fst: snd: genList (n: f (elemAt fst n) (elemAt snd n)) (min (length fst) (length snd))
@ -161,21 +264,37 @@ rec {
else []; else [];
in zipListsWith' 0; in zipListsWith' 0;
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest.
Example:
zipLists [ 1 2 ] [ "a" "b" ]
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]
*/
zipLists = zipListsWith (fst: snd: { inherit fst snd; }); zipLists = zipListsWith (fst: snd: { inherit fst snd; });
/* Reverse the order of the elements of a list.
# Reverse the order of the elements of a list. Example:
reverseList [ "b" "o" "j" ]
=> [ "j" "o" "b" ]
*/
reverseList = reverseList =
if builtins ? genList then if builtins ? genList then
xs: let l = length xs; in genList (n: elemAt xs (l - n - 1)) l xs: let l = length xs; in genList (n: elemAt xs (l - n - 1)) l
else else
fold (e: acc: acc ++ [ e ]) []; fold (e: acc: acc ++ [ e ]) [];
/* Sort a list based on a comparator function which compares two
elements and returns true if the first argument is strictly below
the second argument. The returned list is sorted in an increasing
order. The implementation does a quick-sort.
# Sort a list based on a comparator function which compares two Example:
# elements and returns true if the first argument is strictly below sort (a: b: a < b) [ 5 3 7 ]
# the second argument. The returned list is sorted in an increasing => [ 3 5 7 ]
# order. The implementation does a quick-sort. */
sort = builtins.sort or ( sort = builtins.sort or (
strictLess: list: strictLess: list:
let let
@ -193,8 +312,14 @@ rec {
if len < 2 then list if len < 2 then list
else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right)); else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right));
/* Return the first (at most) N elements of a list.
# Return the first (at most) N elements of a list. Example:
take 2 [ "a" "b" "c" "d" ]
=> [ "a" "b" ]
take 2 [ ]
=> [ ]
*/
take = take =
if builtins ? genList then if builtins ? genList then
count: sublist 0 count count: sublist 0 count
@ -209,8 +334,14 @@ rec {
[ (elemAt list n) ] ++ take' (n + 1); [ (elemAt list n) ] ++ take' (n + 1);
in take' 0; in take' 0;
/* Remove the first (at most) N elements of a list.
# Remove the first (at most) N elements of a list. Example:
drop 2 [ "a" "b" "c" "d" ]
=> [ "c" "d" ]
drop 2 [ ]
=> [ ]
*/
drop = drop =
if builtins ? genList then if builtins ? genList then
count: list: sublist count (length list) list count: list: sublist count (length list) list
@ -225,9 +356,15 @@ rec {
drop' (n - 1) ++ [ (elemAt list n) ]; drop' (n - 1) ++ [ (elemAt list n) ];
in drop' (len - 1); in drop' (len - 1);
/* Return a list consisting of at most count elements of list,
starting at index start.
# Return a list consisting of at most count elements of list, Example:
# starting at index start. sublist 1 3 [ "a" "b" "c" "d" "e" ]
=> [ "b" "c" "d" ]
sublist 1 3 [ ]
=> [ ]
*/
sublist = start: count: list: sublist = start: count: list:
let len = length list; in let len = length list; in
genList genList
@ -236,23 +373,36 @@ rec {
else if start + count > len then len - start else if start + count > len then len - start
else count); else count);
/* Return the last element of a list.
# Return the last element of a list. Example:
last [ 1 2 3 ]
=> 3
*/
last = list: last = list:
assert list != []; elemAt list (length list - 1); assert list != []; elemAt list (length list - 1);
/* Return all elements but the last
# Return all elements but the last Example:
init [ 1 2 3 ]
=> [ 1 2 ]
*/
init = list: assert list != []; take (length list - 1) list; init = list: assert list != []; take (length list - 1) list;
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y; /* FIXME(zimbatm) Not used anywhere
*/
crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f]; crossLists = f: foldl (fs: args: concatMap (f: map f args) fs) [f];
# Remove duplicate elements from the list. O(n^2) complexity. /* Remove duplicate elements from the list. O(n^2) complexity.
Example:
unique [ 3 2 3 4 ]
=> [ 3 2 4 ]
*/
unique = list: unique = list:
if list == [] then if list == [] then
[] []
@ -262,12 +412,24 @@ rec {
xs = unique (drop 1 list); xs = unique (drop 1 list);
in [x] ++ remove x xs; in [x] ++ remove x xs;
/* Intersects list 'e' and another list. O(nm) complexity.
# Intersects list 'e' and another list. O(nm) complexity. Example:
intersectLists [ 1 2 3 ] [ 6 3 2 ]
=> [ 3 2 ]
*/
intersectLists = e: filter (x: elem x e); intersectLists = e: filter (x: elem x e);
/* Subtracts list 'e' from another list. O(nm) complexity.
# Subtracts list 'e' from another list. O(nm) complexity. Example:
subtractLists [ 3 2 ] [ 1 2 3 4 5 3 ]
=> [ 1 4 5 ]
*/
subtractLists = e: filter (x: !(elem x e)); subtractLists = e: filter (x: !(elem x e));
/*** deprecated stuff ***/
deepSeqList = throw "removed 2016-02-29 because unused and broken";
} }

View File

@ -12,6 +12,7 @@
abbradar = "Nikolay Amiantov <ab@fmap.me>"; abbradar = "Nikolay Amiantov <ab@fmap.me>";
aboseley = "Adam Boseley <adam.boseley@gmail.com>"; aboseley = "Adam Boseley <adam.boseley@gmail.com>";
adev = "Adrien Devresse <adev@adev.name>"; adev = "Adrien Devresse <adev@adev.name>";
Adjective-Object = "Maxwell Huang-Hobbs <mhuan13@gmail.com>";
aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>"; aespinosa = "Allan Espinosa <allan.espinosa@outlook.com>";
aflatter = "Alexander Flatter <flatter@fastmail.fm>"; aflatter = "Alexander Flatter <flatter@fastmail.fm>";
aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>"; aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>";
@ -59,6 +60,7 @@
bodil = "Bodil Stokke <nix@bodil.org>"; bodil = "Bodil Stokke <nix@bodil.org>";
boothead = "Ben Ford <ben@perurbis.com>"; boothead = "Ben Ford <ben@perurbis.com>";
bosu = "Boris Sukholitko <boriss@gmail.com>"; bosu = "Boris Sukholitko <boriss@gmail.com>";
bradediger = "Brad Ediger <brad@bradediger.com>";
bramd = "Bram Duvigneau <bram@bramd.nl>"; bramd = "Bram Duvigneau <bram@bramd.nl>";
bstrik = "Berno Strik <dutchman55@gmx.com>"; bstrik = "Berno Strik <dutchman55@gmx.com>";
bzizou = "Bruno Bzeznik <Bruno@bzizou.net>"; bzizou = "Bruno Bzeznik <Bruno@bzizou.net>";
@ -123,6 +125,7 @@
fpletz = "Franz Pletz <fpletz@fnordicwalking.de>"; fpletz = "Franz Pletz <fpletz@fnordicwalking.de>";
fps = "Florian Paul Schmidt <mista.tapas@gmx.net>"; fps = "Florian Paul Schmidt <mista.tapas@gmx.net>";
fridh = "Frederik Rietdijk <fridh@fridh.nl>"; fridh = "Frederik Rietdijk <fridh@fridh.nl>";
frlan = "Frank Lanitz <frank@frank.uvena.de>";
fro_ozen = "fro_ozen <fro_ozen@gmx.de>"; fro_ozen = "fro_ozen <fro_ozen@gmx.de>";
ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>"; ftrvxmtrx = "Siarhei Zirukin <ftrvxmtrx@gmail.com>";
funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>"; funfunctor = "Edward O'Callaghan <eocallaghan@alterapraxis.com>";
@ -152,7 +155,6 @@
iElectric = "Domen Kozar <domen@dev.si>"; iElectric = "Domen Kozar <domen@dev.si>";
igsha = "Igor Sharonov <igor.sharonov@gmail.com>"; igsha = "Igor Sharonov <igor.sharonov@gmail.com>";
ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>"; ikervagyok = "Balázs Lengyel <ikervagyok@gmail.com>";
iyzsong = "Song Wenwu <iyzsong@gmail.com>";
j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>"; j-keck = "Jürgen Keck <jhyphenkeck@gmail.com>";
jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>"; jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>";
javaguirre = "Javier Aguirre <contacto@javaguirre.net>"; javaguirre = "Javier Aguirre <contacto@javaguirre.net>";
@ -208,10 +210,12 @@
malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>"; malyn = "Michael Alyn Miller <malyn@strangeGizmo.com>";
manveru = "Michael Fellinger <m.fellinger@gmail.com>"; manveru = "Michael Fellinger <m.fellinger@gmail.com>";
marcweber = "Marc Weber <marco-oweber@gmx.de>"; marcweber = "Marc Weber <marco-oweber@gmx.de>";
markus1189 = "Markus Hauck <markus1189@gmail.com>";
markWot = "Markus Wotringer <markus@wotringer.de>"; markWot = "Markus Wotringer <markus@wotringer.de>";
matejc = "Matej Cotman <cotman.matej@gmail.com>"; matejc = "Matej Cotman <cotman.matej@gmail.com>";
mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>"; mathnerd314 = "Mathnerd314 <mathnerd314.gph+hs@gmail.com>";
matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>"; matthiasbeyer = "Matthias Beyer <mail@beyermatthias.de>";
mbauer = "Matthew Bauer <mjbauer95@gmail.com>";
maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>"; maurer = "Matthew Maurer <matthew.r.maurer+nix@gmail.com>";
mbakke = "Marius Bakke <ymse@tuta.io>"; mbakke = "Marius Bakke <ymse@tuta.io>";
mbe = "Brandon Edens <brandonedens@gmail.com>"; mbe = "Brandon Edens <brandonedens@gmail.com>";
@ -248,6 +252,7 @@
olcai = "Erik Timan <dev@timan.info>"; olcai = "Erik Timan <dev@timan.info>";
orbitz = "Malcolm Matalka <mmatalka@gmail.com>"; orbitz = "Malcolm Matalka <mmatalka@gmail.com>";
osener = "Ozan Sener <ozan@ozansener.com>"; osener = "Ozan Sener <ozan@ozansener.com>";
otwieracz = "Slawomir Gonet <slawek@otwiera.cz>";
oxij = "Jan Malakhovski <oxij@oxij.org>"; oxij = "Jan Malakhovski <oxij@oxij.org>";
page = "Carles Pagès <page@cubata.homelinux.net>"; page = "Carles Pagès <page@cubata.homelinux.net>";
paholg = "Paho Lurie-Gregg <paho@paholg.com>"; paholg = "Paho Lurie-Gregg <paho@paholg.com>";
@ -255,6 +260,7 @@
palo = "Ingolf Wanger <palipalo9@googlemail.com>"; palo = "Ingolf Wanger <palipalo9@googlemail.com>";
pashev = "Igor Pashev <pashev.igor@gmail.com>"; pashev = "Igor Pashev <pashev.igor@gmail.com>";
pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>"; pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>";
peterhoeg = "Peter Hoeg <peter@hoeg.com>";
philandstuff = "Philip Potter <philip.g.potter@gmail.com>"; philandstuff = "Philip Potter <philip.g.potter@gmail.com>";
phile314 = "Philipp Hausmann <nix@314.ch>"; phile314 = "Philipp Hausmann <nix@314.ch>";
Phlogistique = "Noé Rubinstein <noe.rubinstein@gmail.com>"; Phlogistique = "Noé Rubinstein <noe.rubinstein@gmail.com>";
@ -273,6 +279,7 @@
psibi = "Sibi <sibi@psibi.in>"; psibi = "Sibi <sibi@psibi.in>";
pSub = "Pascal Wittmann <mail@pascal-wittmann.de>"; pSub = "Pascal Wittmann <mail@pascal-wittmann.de>";
puffnfresh = "Brian McKenna <brian@brianmckenna.org>"; puffnfresh = "Brian McKenna <brian@brianmckenna.org>";
pxc = "Patrick Callahan <patrick.callahan@latitudeengineering.com>";
qknight = "Joachim Schiele <js@lastlog.de>"; qknight = "Joachim Schiele <js@lastlog.de>";
ragge = "Ragnar Dahlen <r.dahlen@gmail.com>"; ragge = "Ragnar Dahlen <r.dahlen@gmail.com>";
raskin = "Michael Raskin <7c6f434c@mail.ru>"; raskin = "Michael Raskin <7c6f434c@mail.ru>";
@ -293,13 +300,16 @@
rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>"; rushmorem = "Rushmore Mushambi <rushmore@webenchanter.com>";
rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>"; rvl = "Rodney Lorrimar <dev+nix@rodney.id.au>";
rvlander = "Gaëtan André <rvlander@gaetanandre.eu>"; rvlander = "Gaëtan André <rvlander@gaetanandre.eu>";
ryanartecona = "Ryan Artecona <ryanartecona@gmail.com>";
ryantm = "Ryan Mulligan <ryan@ryantm.com>"; ryantm = "Ryan Mulligan <ryan@ryantm.com>";
rycee = "Robert Helgesson <robert@rycee.net>"; rycee = "Robert Helgesson <robert@rycee.net>";
samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>"; samuelrivas = "Samuel Rivas <samuelrivas@gmail.com>";
sander = "Sander van der Burg <s.vanderburg@tudelft.nl>"; sander = "Sander van der Burg <s.vanderburg@tudelft.nl>";
schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>"; schmitthenner = "Fabian Schmitthenner <development@schmitthenner.eu>";
schristo = "Scott Christopher <schristopher@konputa.com>"; schristo = "Scott Christopher <schristopher@konputa.com>";
scolobb = "Sergiu Ivanov <sivanov@colimite.fr>";
sepi = "Raffael Mancini <raffael@mancini.lu>"; sepi = "Raffael Mancini <raffael@mancini.lu>";
sheenobu = "Sheena Artrip <sheena.artrip@gmail.com>";
sheganinans = "Aistis Raulinaitis <sheganinans@gmail.com>"; sheganinans = "Aistis Raulinaitis <sheganinans@gmail.com>";
shell = "Shell Turner <cam.turn@gmail.com>"; shell = "Shell Turner <cam.turn@gmail.com>";
shlevy = "Shea Levy <shea@shealevy.com>"; shlevy = "Shea Levy <shea@shealevy.com>";
@ -309,6 +319,7 @@
sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>"; sjmackenzie = "Stewart Mackenzie <setori88@gmail.com>";
sjourdois = "Stéphane kwisatz Jourdois <sjourdois@gmail.com>"; sjourdois = "Stéphane kwisatz Jourdois <sjourdois@gmail.com>";
skeidel = "Sven Keidel <svenkeidel@gmail.com>"; skeidel = "Sven Keidel <svenkeidel@gmail.com>";
skrzyp = "Jakub Skrzypnik <jot.skrzyp@gmail.com>";
sleexyz = "Sean Lee <freshdried@gmail.com>"; sleexyz = "Sean Lee <freshdried@gmail.com>";
smironov = "Sergey Mironov <ierton@gmail.com>"; smironov = "Sergey Mironov <ierton@gmail.com>";
spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>"; spacefrogg = "Michael Raitza <spacefrogg-nixos@meterriblecrew.net>";
@ -341,6 +352,7 @@
tv = "Tomislav Viljetić <tv@shackspace.de>"; tv = "Tomislav Viljetić <tv@shackspace.de>";
tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>"; tvestelind = "Tomas Vestelind <tomas.vestelind@fripost.org>";
twey = "James Twey Kay <twey@twey.co.uk>"; twey = "James Twey Kay <twey@twey.co.uk>";
uralbash = "Svintsov Dmitry <root@uralbash.ru>";
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
vandenoever = "Jos van den Oever <jos@vandenoever.info>"; vandenoever = "Jos van den Oever <jos@vandenoever.info>";
vanzef = "Ivan Solyankin <vanzef@gmail.com>"; vanzef = "Ivan Solyankin <vanzef@gmail.com>";

View File

@ -15,7 +15,7 @@ Usage:
Attention: Attention:
let let
pkgs = (import /etc/nixos/nixpkgs/pkgs/top-level/all-packages.nix) {}; pkgs = (import <nixpkgs>) {};
in let in let
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap; inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
inherit (pkgs.lib) id; inherit (pkgs.lib) id;

View File

@ -10,65 +10,147 @@ rec {
inherit (builtins) stringLength substring head tail isString replaceStrings; inherit (builtins) stringLength substring head tail isString replaceStrings;
/* Concatenate a list of strings.
# Concatenate a list of strings. Example:
concatStrings ["foo" "bar"]
=> "foobar"
*/
concatStrings = concatStrings =
if builtins ? concatStringsSep then if builtins ? concatStringsSep then
builtins.concatStringsSep "" builtins.concatStringsSep ""
else else
lib.foldl' (x: y: x + y) ""; lib.foldl' (x: y: x + y) "";
/* Map a function over a list and concatenate the resulting strings.
# Map a function over a list and concatenate the resulting strings. Example:
concatMapStrings (x: "a" + x) ["foo" "bar"]
=> "afooabar"
*/
concatMapStrings = f: list: concatStrings (map f list); concatMapStrings = f: list: concatStrings (map f list);
/* Like `concatMapStrings' except that the f functions also gets the
position as a parameter.
Example:
concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"]
=> "1-foo2-bar"
*/
concatImapStrings = f: list: concatStrings (lib.imap f list); concatImapStrings = f: list: concatStrings (lib.imap f list);
/* Place an element between each element of a list
# Place an element between each element of a list, e.g., Example:
# `intersperse "," ["a" "b" "c"]' returns ["a" "," "b" "," "c"]. intersperse "/" ["usr" "local" "bin"]
=> ["usr" "/" "local" "/" "bin"].
*/
intersperse = separator: list: intersperse = separator: list:
if list == [] || length list == 1 if list == [] || length list == 1
then list then list
else tail (lib.concatMap (x: [separator x]) list); else tail (lib.concatMap (x: [separator x]) list);
/* Concatenate a list of strings with a separator between each element
# Concatenate a list of strings with a separator between each element, e.g. Example:
# concatStringsSep " " ["foo" "bar" "xyzzy"] == "foo bar xyzzy" concatStringsSep "/" ["usr" "local" "bin"]
=> "usr/local/bin"
*/
concatStringsSep = builtins.concatStringsSep or (separator: list: concatStringsSep = builtins.concatStringsSep or (separator: list:
concatStrings (intersperse separator list)); concatStrings (intersperse separator list));
/* First maps over the list and then concatenates it.
Example:
concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"]
=> "FOO-BAR-BAZ"
*/
concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list); concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list);
/* First imaps over the list and then concatenates it.
Example:
concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ]
=> "6-3-2"
*/
concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap f list); concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap f list);
/* Construct a Unix-style search path consisting of each `subDir"
directory of the given list of packages.
# Construct a Unix-style search path consisting of each `subDir" Example:
# directory of the given list of packages. For example, makeSearchPath "bin" ["/root" "/usr" "/usr/local"]
# `makeSearchPath "bin" ["x" "y" "z"]' returns "x/bin:y/bin:z/bin". => "/root/bin:/usr/bin:/usr/local/bin"
makeSearchPath "bin" ["/"]
=> "//bin"
*/
makeSearchPath = subDir: packages: makeSearchPath = subDir: packages:
concatStringsSep ":" (map (path: path + "/" + subDir) packages); concatStringsSep ":" (map (path: path + "/" + subDir) packages);
/* Construct a library search path (such as RPATH) containing the
libraries for a set of packages
# Construct a library search path (such as RPATH) containing the Example:
# libraries for a set of packages, e.g. "${pkg1}/lib:${pkg2}/lib:...". makeLibraryPath [ "/usr" "/usr/local" ]
=> "/usr/lib:/usr/local/lib"
pkgs = import <nixpkgs> { }
makeLibraryPath [ pkgs.openssl pkgs.zlib ]
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r/lib:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/lib"
*/
makeLibraryPath = makeSearchPath "lib"; makeLibraryPath = makeSearchPath "lib";
# Construct a binary search path (such as $PATH) containing the /* Construct a binary search path (such as $PATH) containing the
# binaries for a set of packages, e.g. "${pkg1}/bin:${pkg2}/bin:...". binaries for a set of packages.
Example:
makeBinPath ["/root" "/usr" "/usr/local"]
=> "/root/bin:/usr/bin:/usr/local/bin"
*/
makeBinPath = makeSearchPath "bin"; makeBinPath = makeSearchPath "bin";
# Idem for Perl search paths. /* Construct a perl search path (such as $PERL5LIB)
FIXME(zimbatm): this should be moved in perl-specific code
Example:
pkgs = import <nixpkgs> { }
makePerlPath [ pkgs.perlPackages.NetSMTP ]
=> "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl"
*/
makePerlPath = makeSearchPath "lib/perl5/site_perl"; makePerlPath = makeSearchPath "lib/perl5/site_perl";
/* Dependening on the boolean `cond', return either the given string
or the empty string. Useful to contatenate against a bigger string.
# Dependening on the boolean `cond', return either the given string Example:
# or the empty string. optionalString true "some-string"
=> "some-string"
optionalString false "some-string"
=> ""
*/
optionalString = cond: string: if cond then string else ""; optionalString = cond: string: if cond then string else "";
/* Determine whether a string has given prefix.
# Determine whether a string has given prefix/suffix. Example:
hasPrefix "foo" "foobar"
=> true
hasPrefix "foo" "barfoo"
=> false
*/
hasPrefix = pref: str: hasPrefix = pref: str:
substring 0 (stringLength pref) str == pref; substring 0 (stringLength pref) str == pref;
/* Determine whether a string has given suffix.
Example:
hasSuffix "foo" "foobar"
=> false
hasSuffix "foo" "barfoo"
=> true
*/
hasSuffix = suff: str: hasSuffix = suff: str:
let let
lenStr = stringLength str; lenStr = stringLength str;
@ -76,36 +158,55 @@ rec {
in lenStr >= lenSuff && in lenStr >= lenSuff &&
substring (lenStr - lenSuff) lenStr str == suff; substring (lenStr - lenSuff) lenStr str == suff;
/* Convert a string to a list of characters (i.e. singleton strings).
This allows you to, e.g., map a function over each character. However,
note that this will likely be horribly inefficient; Nix is not a
general purpose programming language. Complex string manipulations
should, if appropriate, be done in a derivation.
Also note that Nix treats strings as a list of bytes and thus doesn't
handle unicode.
# Convert a string to a list of characters (i.e. singleton strings). Example:
# For instance, "abc" becomes ["a" "b" "c"]. This allows you to, stringToCharacters ""
# e.g., map a function over each character. However, note that this => [ ]
# will likely be horribly inefficient; Nix is not a general purpose stringToCharacters "abc"
# programming language. Complex string manipulations should, if => [ "a" "b" "c" ]
# appropriate, be done in a derivation. stringToCharacters "💩"
=> [ "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" ]
*/
stringToCharacters = s: stringToCharacters = s:
map (p: substring p 1 s) (lib.range 0 (stringLength s - 1)); map (p: substring p 1 s) (lib.range 0 (stringLength s - 1));
/* Manipulate a string character by character and replace them by
strings before concatenating the results.
# Manipulate a string charactter by character and replace them by Example:
# strings before concatenating the results. stringAsChars (x: if x == "a" then "i" else x) "nax"
=> "nix"
*/
stringAsChars = f: s: stringAsChars = f: s:
concatStrings ( concatStrings (
map f (stringToCharacters s) map f (stringToCharacters s)
); );
/* Escape occurrence of the elements of list in string by
prefixing it with a backslash.
# Escape occurrence of the elements of list in string by Example:
# prefixing it with a backslash. For example, escape ["(" ")"] escape ["(" ")"] "(foo)"
# "(foo)" returns the string \(foo\). => "\\(foo\\)"
*/
escape = list: replaceChars list (map (c: "\\${c}") list); escape = list: replaceChars list (map (c: "\\${c}") list);
/* Escape all characters that have special meaning in the Bourne shell.
# Escape all characters that have special meaning in the Bourne shell. Example:
escapeShellArg "so([<>])me"
=> "so\\(\\[\\<\\>\\]\\)me"
*/
escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]"); escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]");
/* Obsolete - use replaceStrings instead. */
# Obsolete - use replaceStrings instead.
replaceChars = builtins.replaceStrings or ( replaceChars = builtins.replaceStrings or (
del: new: s: del: new: s:
let let
@ -119,21 +220,52 @@ rec {
in in
stringAsChars subst s); stringAsChars subst s);
# Case conversion utilities. # Case conversion utilities.
lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz"; lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz";
upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/* Converts an ASCII string to lower-case.
Example:
toLower "HOME"
=> "home"
*/
toLower = replaceChars upperChars lowerChars; toLower = replaceChars upperChars lowerChars;
/* Converts an ASCII string to upper-case.
Example:
toLower "home"
=> "HOME"
*/
toUpper = replaceChars lowerChars upperChars; toUpper = replaceChars lowerChars upperChars;
/* Appends string context from another string. This is an implementation
detail of Nix.
# Appends string context from another string. Strings in Nix carry an invisible `context' which is a list of strings
representing store paths. If the string is later used in a derivation
attribute, the derivation will properly populate the inputDrvs and
inputSrcs.
Example:
pkgs = import <nixpkgs> { };
addContextFrom pkgs.coreutils "bar"
=> "bar"
*/
addContextFrom = a: b: substring 0 0 a + b; addContextFrom = a: b: substring 0 0 a + b;
/* Cut a string with a separator and produces a list of strings which
were separated by this separator.
# Cut a string with a separator and produces a list of strings which NOTE: this function is not performant and should be avoided
# were separated by this separator; e.g., `splitString "."
# "foo.bar.baz"' returns ["foo" "bar" "baz"]. Example:
splitString "." "foo.bar.baz"
=> [ "foo" "bar" "baz" ]
splitString "/" "/usr/local/bin"
=> [ "" "usr" "local" "bin" ]
*/
splitString = _sep: _s: splitString = _sep: _s:
let let
sep = addContextFrom _s _sep; sep = addContextFrom _s _sep;
@ -157,10 +289,15 @@ rec {
in in
recurse 0 0; recurse 0 0;
/* Return the suffix of the second argument if the first argument matches
its prefix.
# return the suffix of the second argument if the first argument match its Example:
# prefix. e.g., removePrefix "foo." "foo.bar.baz"
# `removePrefix "foo." "foo.bar.baz"' returns "bar.baz". => "bar.baz"
removePrefix "xxx" "foo.bar.baz"
=> "foo.bar.baz"
*/
removePrefix = pre: s: removePrefix = pre: s:
let let
preLen = stringLength pre; preLen = stringLength pre;
@ -171,6 +308,15 @@ rec {
else else
s; s;
/* Return the prefix of the second argument if the first argument matches
its suffix.
Example:
removeSuffix "front" "homefront"
=> "home"
removeSuffix "xxx" "homefront"
=> "homefront"
*/
removeSuffix = suf: s: removeSuffix = suf: s:
let let
sufLen = stringLength suf; sufLen = stringLength suf;
@ -181,25 +327,49 @@ rec {
else else
s; s;
# Return true iff string v1 denotes a version older than v2. /* Return true iff string v1 denotes a version older than v2.
Example:
versionOlder "1.1" "1.2"
=> true
versionOlder "1.1" "1.1"
=> false
*/
versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1; versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1;
/* Return true iff string v1 denotes a version equal to or newer than v2.
# Return true iff string v1 denotes a version equal to or newer than v2. Example:
versionAtLeast "1.1" "1.0"
=> true
versionAtLeast "1.1" "1.1"
=> true
versionAtLeast "1.1" "1.2"
=> false
*/
versionAtLeast = v1: v2: !versionOlder v1 v2; versionAtLeast = v1: v2: !versionOlder v1 v2;
/* This function takes an argument that's either a derivation or a
derivation's "name" attribute and extracts the version part from that
argument.
# This function takes an argument that's either a derivation or a Example:
# derivation's "name" attribute and extracts the version part from that getVersion "youtube-dl-2016.01.01"
# argument. For example: => "2016.01.01"
# getVersion pkgs.youtube-dl
# lib.getVersion "youtube-dl-2016.01.01" ==> "2016.01.01" => "2016.01.01"
# lib.getVersion pkgs.youtube-dl ==> "2016.01.01" */
getVersion = x: (builtins.parseDrvName (x.name or x)).version; getVersion = x: (builtins.parseDrvName (x.name or x)).version;
/* Extract name with version from URL. Ask for separator which is
supposed to start extension.
# Extract name with version from URL. Ask for separator which is Example:
# supposed to start extension. nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "-"
=> "nix"
nameFromURL "https://nixos.org/releases/nix/nix-1.7/nix-1.7-x86_64-linux.tar.bz2" "_"
=> "nix-1.7-x86"
*/
nameFromURL = url: sep: nameFromURL = url: sep:
let let
components = splitString "/" url; components = splitString "/" url;
@ -207,14 +377,24 @@ rec {
name = builtins.head (splitString sep filename); name = builtins.head (splitString sep filename);
in assert name != filename; name; in assert name != filename; name;
/* Create an --{enable,disable}-<feat> string that can be passed to
standard GNU Autoconf scripts.
# Create an --{enable,disable}-<feat> string that can be passed to Example:
# standard GNU Autoconf scripts. enableFeature true "shared"
=> "--enable-shared"
enableFeature false "shared"
=> "--disable-shared"
*/
enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}"; enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}";
/* Create a fixed width string with additional prefix to match
required width.
# Create a fixed width string with additional prefix to match Example:
# required width. fixedWidthString 5 "0" (toString 15)
=> "00015"
*/
fixedWidthString = width: filler: str: fixedWidthString = width: filler: str:
let let
strw = lib.stringLength str; strw = lib.stringLength str;
@ -223,25 +403,58 @@ rec {
assert strw <= width; assert strw <= width;
if strw == width then str else filler + fixedWidthString reqWidth filler str; if strw == width then str else filler + fixedWidthString reqWidth filler str;
/* Format a number adding leading zeroes up to fixed width.
# Format a number adding leading zeroes up to fixed width. Example:
fixedWidthNumber 5 15
=> "00015"
*/
fixedWidthNumber = width: n: fixedWidthString width "0" (toString n); fixedWidthNumber = width: n: fixedWidthString width "0" (toString n);
/* Check whether a value is a store path.
# Check whether a value is a store path. Example:
isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11/bin/python"
=> false
isStorePath "/nix/store/d945ibfx9x185xf04b890y4f9g3cbb63-python-2.7.11/"
=> true
isStorePath pkgs.python
=> true
*/
isStorePath = x: builtins.substring 0 1 (toString x) == "/" && dirOf (builtins.toPath x) == builtins.storeDir; isStorePath = x: builtins.substring 0 1 (toString x) == "/" && dirOf (builtins.toPath x) == builtins.storeDir;
# Convert string to int /* Convert string to int
# Obviously, it is a bit hacky to use fromJSON that way. Obviously, it is a bit hacky to use fromJSON that way.
Example:
toInt "1337"
=> 1337
toInt "-4"
=> -4
toInt "3.14"
=> error: floating point JSON numbers are not supported
*/
toInt = str: toInt = str:
let may_be_int = builtins.fromJSON str; in let may_be_int = builtins.fromJSON str; in
if builtins.isInt may_be_int if builtins.isInt may_be_int
then may_be_int then may_be_int
else throw "Could not convert ${str} to int."; else throw "Could not convert ${str} to int.";
# Read a list of paths from `file', relative to the `rootPath'. Lines /* Read a list of paths from `file', relative to the `rootPath'. Lines
# beginning with `#' are treated as comments and ignored. Whitespace beginning with `#' are treated as comments and ignored. Whitespace
# is significant. is significant.
NOTE: this function is not performant and should be avoided
Example:
readPathsFromFile /prefix
./pkgs/development/libraries/qt-5/5.4/qtbase/series
=> [ "/prefix/dlopen-resolv.patch" "/prefix/tzdir.patch"
"/prefix/dlopen-libXcursor.patch" "/prefix/dlopen-openssl.patch"
"/prefix/dlopen-dbus.patch" "/prefix/xdg-config-dirs.patch"
"/prefix/nix-profiles-library-paths.patch"
"/prefix/compose-search-path.patch" ]
*/
readPathsFromFile = rootPath: file: readPathsFromFile = rootPath: file:
let let
root = toString rootPath; root = toString rootPath;
@ -253,5 +466,4 @@ rec {
absolutePaths = builtins.map (path: builtins.toPath (root + "/" + path)) relativePaths; absolutePaths = builtins.map (path: builtins.toPath (root + "/" + path)) relativePaths;
in in
absolutePaths; absolutePaths;
} }

View File

@ -187,6 +187,7 @@ in rec {
--param man.output.in.separate.dir 1 \ --param man.output.in.separate.dir 1 \
--param man.output.base.dir "'$out/share/man/'" \ --param man.output.base.dir "'$out/share/man/'" \
--param man.endnotes.are.numbered 0 \ --param man.endnotes.are.numbered 0 \
--param man.break.after.slash 1 \
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \ ${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
./man-pages.xml ./man-pages.xml
''; '';

View File

@ -22,7 +22,10 @@
(with empty password).</para></listitem> (with empty password).</para></listitem>
<listitem><para>If you downloaded the graphical ISO image, you can <listitem><para>If you downloaded the graphical ISO image, you can
run <command>start display-manager</command> to start KDE.</para></listitem> run <command>start display-manager</command> to start KDE. If you
want to continue on the terminal, you can use
<command>loadkeys</command> to switch to your preferred keyboard layout.
(We even provide neo2 via <command>loadkeys de neo</command>!)</para></listitem>
<listitem><para>The boot process should have brought up networking (check <listitem><para>The boot process should have brought up networking (check
<command>ip a</command>). Networking is necessary for the <command>ip a</command>). Networking is necessary for the

View File

@ -247,6 +247,33 @@ $TTL 1800
</programlisting> </programlisting>
</listitem> </listitem>
<listitem>
<para>
<literal>service.syncthing.dataDir</literal> options now has to point
to exact folder where syncthing is writing to. Example configuration should
loook something like:
</para>
<programlisting>
services.syncthing = {
enable = true;
dataDir = "/home/somebody/.syncthing";
user = "somebody";
};
</programlisting>
</listitem>
<listitem>
<para>
<literal>networking.firewall.allowPing</literal> is now enabled by
default. Users are encourarged to configure an approiate rate limit for
their machines using the Kernel interface at
<filename>/proc/sys/net/ipv4/icmp_ratelimit</filename> and
<filename>/proc/sys/net/ipv6/icmp/ratelimit</filename> or using the
firewall itself, i.e. by setting the NixOS option
<literal>networking.firewall.pingLimit</literal>.
</para>
</listitem>
</itemizedlist> </itemizedlist>

View File

@ -22,12 +22,13 @@
, # Shell code executed after the VM has finished. , # Shell code executed after the VM has finished.
postVM ? "" postVM ? ""
, name ? "nixos-disk-image"
}: }:
with lib; with lib;
pkgs.vmTools.runInLinuxVM ( pkgs.vmTools.runInLinuxVM (
pkgs.runCommand "nixos-disk-image" pkgs.runCommand name
{ preVM = { preVM =
'' ''
mkdir $out mkdir $out

View File

@ -22,7 +22,7 @@
, # Whether this should be an efi-bootable El-Torito CD. , # Whether this should be an efi-bootable El-Torito CD.
efiBootable ? false efiBootable ? false
, # Wheter this should be an hybrid CD (bootable from USB as well as CD). , # Whether this should be an hybrid CD (bootable from USB as well as CD).
usbBootable ? false usbBootable ? false
, # The path (in the ISO file system) of the boot image. , # The path (in the ISO file system) of the boot image.
@ -39,7 +39,6 @@
, # The volume ID. , # The volume ID.
volumeID ? "" volumeID ? ""
}: }:
assert bootable -> bootImage != ""; assert bootable -> bootImage != "";
@ -47,7 +46,7 @@ assert efiBootable -> efiBootImage != "";
assert usbBootable -> isohybridMbrImage != ""; assert usbBootable -> isohybridMbrImage != "";
stdenv.mkDerivation { stdenv.mkDerivation {
name = "iso9660-image"; name = isoName;
builder = ./make-iso9660-image.sh; builder = ./make-iso9660-image.sh;
buildInputs = [perl xorriso syslinux]; buildInputs = [perl xorriso syslinux];

View File

@ -133,3 +133,4 @@ fi
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo $system > $out/nix-support/system echo $system > $out/nix-support/system
echo "file iso $out/iso/$isoName" >> $out/nix-support/hydra-build-products

View File

@ -1,11 +1,8 @@
#! /bin/sh -e #! /bin/sh -e
BUCKET_NAME=${BUCKET_NAME:-nixos}
export NIX_PATH=nixpkgs=../../../.. export NIX_PATH=nixpkgs=../../../..
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/azure-image.nix export NIXOS_CONFIG=$(dirname $(readlink -f $0))/../../../modules/virtualisation/azure-image.nix
export TIMESTAMP=$(date +%Y%m%d%H%M) export TIMESTAMP=$(date +%Y%m%d%H%M)
nix-build '<nixpkgs/nixos>' \ nix-build '<nixpkgs/nixos>' \
-A config.system.build.azureImage --argstr system x86_64-linux -o azure --option extra-binary-caches http://hydra.nixos.org -j 10 -A config.system.build.azureImage --argstr system x86_64-linux -o azure --option extra-binary-caches https://hydra.nixos.org -j 10
azure vm image create nixos-test --location "West Europe" --md5-skip -v --os Linux azure/disk.vhd

View File

@ -0,0 +1,22 @@
#! /bin/sh -e
export STORAGE=${STORAGE:-nixos}
export THREADS=${THREADS:-8}
azure-vhd-utils-for-go upload --localvhdpath azure/disk.vhd --stgaccountname "$STORAGE" --stgaccountkey "$KEY" \
--containername images --blobname nixos-unstable-nixops-updated.vhd --parallelism "$THREADS" --overwrite

View File

@ -37,7 +37,6 @@ with lib;
services.openssh.enable = false; services.openssh.enable = false;
services.lshd.enable = true; services.lshd.enable = true;
programs.ssh.startAgent = false; programs.ssh.startAgent = false;
services.xserver.startGnuPGAgent = true;
# TODO: GNU dico. # TODO: GNU dico.
# TODO: GNU Inetutils' inetd. # TODO: GNU Inetutils' inetd.

View File

@ -32,7 +32,7 @@ in
kdc = mkOption { kdc = mkOption {
default = "kerberos.mit.edu"; default = "kerberos.mit.edu";
description = "Kerberos Domain Controller."; description = "Key Distribution Center";
}; };
kerberosAdminServer = mkOption { kerberosAdminServer = mkOption {

View File

@ -103,7 +103,7 @@ in
hardware.opengl.extraPackages32 = mkOption { hardware.opengl.extraPackages32 = mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = []; default = [];
example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]"; example = literalExample "with pkgs.pkgsi686Linux; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]";
description = '' description = ''
Additional packages to add to 32-bit OpenGL drivers on Additional packages to add to 32-bit OpenGL drivers on
64-bit systems. Used when <option>driSupport32Bit</option> is 64-bit systems. Used when <option>driSupport32Bit</option> is

View File

@ -14,6 +14,8 @@ let
nvidiaForKernel = kernelPackages: nvidiaForKernel = kernelPackages:
if elem "nvidia" drivers then if elem "nvidia" drivers then
kernelPackages.nvidia_x11 kernelPackages.nvidia_x11
else if elem "nvidiaBeta" drivers then
kernelPackages.nvidia_x11_beta
else if elem "nvidiaLegacy173" drivers then else if elem "nvidiaLegacy173" drivers then
kernelPackages.nvidia_x11_legacy173 kernelPackages.nvidia_x11_legacy173
else if elem "nvidiaLegacy304" drivers then else if elem "nvidiaLegacy304" drivers then

View File

@ -176,7 +176,6 @@
seeks = 148; seeks = 148;
prosody = 149; prosody = 149;
i2pd = 150; i2pd = 150;
dnscrypt-proxy = 151;
systemd-network = 152; systemd-network = 152;
systemd-resolve = 153; systemd-resolve = 153;
systemd-timesync = 154; systemd-timesync = 154;
@ -254,6 +253,10 @@
octoprint = 230; octoprint = 230;
avahi-autoipd = 231; avahi-autoipd = 231;
nntp-proxy = 232; nntp-proxy = 232;
mjpg-streamer = 233;
radicale = 234;
hydra-queue-runner = 235;
hydra-www = 236;
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
@ -410,7 +413,6 @@
seeks = 148; seeks = 148;
prosody = 149; prosody = 149;
i2pd = 150; i2pd = 150;
dnscrypt-proxy = 151;
systemd-network = 152; systemd-network = 152;
systemd-resolve = 153; systemd-resolve = 153;
systemd-timesync = 154; systemd-timesync = 154;
@ -482,6 +484,7 @@
cfdyndns = 227; cfdyndns = 227;
pdnsd = 229; pdnsd = 229;
octoprint = 230; octoprint = 230;
radicale = 234;
# When adding a gid, make sure it doesn't match an existing # When adding a gid, make sure it doesn't match an existing
# uid. Users and groups with the same name should have equal # uid. Users and groups with the same name should have equal

View File

@ -104,7 +104,7 @@ in
nixosVersion = mkDefault (maybeEnv "NIXOS_VERSION" (cfg.nixosRelease + cfg.nixosVersionSuffix)); nixosVersion = mkDefault (maybeEnv "NIXOS_VERSION" (cfg.nixosRelease + cfg.nixosVersionSuffix));
# Note: code names must only increase in alphabetical order. # Note: code names must only increase in alphabetical order.
nixosCodeName = "Emu"; nixosCodeName = "Flounder";
}; };
# Generate /etc/os-release. See # Generate /etc/os-release. See

View File

@ -114,6 +114,7 @@
./services/backup/rsnapshot.nix ./services/backup/rsnapshot.nix
./services/backup/sitecopy-backup.nix ./services/backup/sitecopy-backup.nix
./services/backup/tarsnap.nix ./services/backup/tarsnap.nix
./services/backup/znapzend.nix
./services/cluster/fleet.nix ./services/cluster/fleet.nix
./services/cluster/kubernetes.nix ./services/cluster/kubernetes.nix
./services/cluster/panamax.nix ./services/cluster/panamax.nix
@ -176,6 +177,7 @@
./services/hardware/udisks2.nix ./services/hardware/udisks2.nix
./services/hardware/upower.nix ./services/hardware/upower.nix
./services/hardware/thermald.nix ./services/hardware/thermald.nix
./services/logging/awstats.nix
./services/logging/fluentd.nix ./services/logging/fluentd.nix
./services/logging/klogd.nix ./services/logging/klogd.nix
./services/logging/logcheck.nix ./services/logging/logcheck.nix
@ -219,6 +221,7 @@
./services/misc/gitolite.nix ./services/misc/gitolite.nix
./services/misc/gpsd.nix ./services/misc/gpsd.nix
./services/misc/ihaskell.nix ./services/misc/ihaskell.nix
./services/misc/mantisbt.nix
./services/misc/mathics.nix ./services/misc/mathics.nix
./services/misc/matrix-synapse.nix ./services/misc/matrix-synapse.nix
./services/misc/mbpfan.nix ./services/misc/mbpfan.nix
@ -329,6 +332,7 @@
./services/networking/lambdabot.nix ./services/networking/lambdabot.nix
./services/networking/libreswan.nix ./services/networking/libreswan.nix
./services/networking/mailpile.nix ./services/networking/mailpile.nix
./services/networking/mjpg-streamer.nix
./services/networking/minidlna.nix ./services/networking/minidlna.nix
./services/networking/miniupnpd.nix ./services/networking/miniupnpd.nix
./services/networking/mstpd.nix ./services/networking/mstpd.nix
@ -439,6 +443,7 @@
./services/web-servers/varnish/default.nix ./services/web-servers/varnish/default.nix
./services/web-servers/winstone.nix ./services/web-servers/winstone.nix
./services/web-servers/zope2.nix ./services/web-servers/zope2.nix
./services/x11/colord.nix
./services/x11/unclutter.nix ./services/x11/unclutter.nix
./services/x11/desktop-managers/default.nix ./services/x11/desktop-managers/default.nix
./services/x11/display-managers/auto.nix ./services/x11/display-managers/auto.nix

View File

@ -17,7 +17,6 @@
pkgs.ddrescue pkgs.ddrescue
pkgs.ccrypt pkgs.ccrypt
pkgs.cryptsetup # needed for dm-crypt volumes pkgs.cryptsetup # needed for dm-crypt volumes
pkgs.which # 88K size
# Some networking tools. # Some networking tools.
pkgs.fuse pkgs.fuse

View File

@ -56,7 +56,7 @@ in
*/ */
shellAliases = mkOption { shellAliases = mkOption {
default = config.environment.shellAliases; default = config.environment.shellAliases // { which = "type -P"; };
description = '' description = ''
Set of aliases for bash shell. See <option>environment.shellAliases</option> Set of aliases for bash shell. See <option>environment.shellAliases</option>
for an option format description. for an option format description.

View File

@ -98,6 +98,9 @@ with lib;
(mkRenamedOptionModule [ "services" "hostapd" "extraCfg" ] [ "services" "hostapd" "extraConfig" ]) (mkRenamedOptionModule [ "services" "hostapd" "extraCfg" ] [ "services" "hostapd" "extraConfig" ])
# Enlightenment
(mkRenamedOptionModule [ "services" "xserver" "desktopManager" "e19" "enable" ] [ "services" "xserver" "desktopManager" "enlightenment" "enable" ])
# Options that are obsolete and have no replacement. # Options that are obsolete and have no replacement.
(mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ]) (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ])
(mkRemovedOptionModule [ "programs" "bash" "enable" ]) (mkRemovedOptionModule [ "programs" "bash" "enable" ])
@ -108,6 +111,7 @@ with lib;
(mkRemovedOptionModule [ "services" "openvpn" "enable" ]) (mkRemovedOptionModule [ "services" "openvpn" "enable" ])
(mkRemovedOptionModule [ "services" "printing" "cupsFilesConf" ]) (mkRemovedOptionModule [ "services" "printing" "cupsFilesConf" ])
(mkRemovedOptionModule [ "services" "printing" "cupsdConf" ]) (mkRemovedOptionModule [ "services" "printing" "cupsdConf" ])
(mkRemovedOptionModule [ "services" "xserver" "startGnuPGAgent" ])
]; ];
} }

View File

@ -26,19 +26,11 @@ in
''; '';
}; };
stable = mkOption { kernelPatch = mkOption {
type = types.bool; type = types.attrs;
default = false; example = lib.literalExample "pkgs.kernelPatches.grsecurity_4_1";
description = '' description = ''
Enable the stable grsecurity patch, based on Linux 3.14. Grsecurity patch to use.
'';
};
testing = mkOption {
type = types.bool;
default = false;
description = ''
Enable the testing grsecurity patch, based on Linux 4.0.
''; '';
}; };
@ -219,16 +211,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = assertions =
[ { assertion = cfg.stable || cfg.testing; [
message = ''
If grsecurity is enabled, you must select either the
stable patch (with kernel 3.14), or the testing patch (with
kernel 4.0) to continue.
'';
}
{ assertion = !(cfg.stable && cfg.testing);
message = "Select either one of the stable or testing patch";
}
{ assertion = (cfg.config.restrictProc -> !cfg.config.restrictProcWithGroup) || { assertion = (cfg.config.restrictProc -> !cfg.config.restrictProcWithGroup) ||
(cfg.config.restrictProcWithGroup -> !cfg.config.restrictProc); (cfg.config.restrictProcWithGroup -> !cfg.config.restrictProc);
message = "You cannot enable both restrictProc and restrictProcWithGroup"; message = "You cannot enable both restrictProc and restrictProcWithGroup";
@ -247,6 +230,8 @@ in
} }
]; ];
security.grsecurity.kernelPatch = lib.mkDefault pkgs.kernelPatches.grsecurity_latest;
systemd.services.grsec-lock = mkIf cfg.config.sysctl { systemd.services.grsec-lock = mkIf cfg.config.sysctl {
description = "grsecurity sysctl-lock Service"; description = "grsecurity sysctl-lock Service";
requires = [ "systemd-sysctl.service" ]; requires = [ "systemd-sysctl.service" ];

View File

@ -48,6 +48,14 @@ with lib;
ensureDir ${crashplan.vardir}/cache 700 ensureDir ${crashplan.vardir}/cache 700
ensureDir ${crashplan.vardir}/backupArchives 700 ensureDir ${crashplan.vardir}/backupArchives 700
ensureDir ${crashplan.vardir}/log 777 ensureDir ${crashplan.vardir}/log 777
cp -avn ${crashplan}/conf.template/* ${crashplan.vardir}/conf
for x in app.asar bin EULA.txt install.vars lang lib libjniwrap64.so libjniwrap.so libjtux64.so libjtux.so libmd564.so libmd5.so share skin upgrade; do
if [ -e $x ]; then
true;
else
ln -s ${crashplan}/$x ${crashplan.vardir}/$x;
fi;
done
''; '';
serviceConfig = { serviceConfig = {

View File

@ -293,7 +293,7 @@ in
# make sure that the tarsnap server is reachable after systemd starts up # make sure that the tarsnap server is reachable after systemd starts up
# the service - therefore we sleep in a loop until we can ping the # the service - therefore we sleep in a loop until we can ping the
# endpoint. # endpoint.
preStart = "while ! ping -q -c 1 betatest-server.tarsnap.com &> /dev/null; do sleep 3; done"; preStart = "while ! ping -q -c 1 v1-0-0-server.tarsnap.com &> /dev/null; do sleep 3; done";
scriptArgs = "%i"; scriptArgs = "%i";
script = '' script = ''
mkdir -p -m 0755 ${dirOf cfg.cachedir} mkdir -p -m 0755 ${dirOf cfg.cachedir}

View File

@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.znapzend;
in
{
options = {
services.znapzend = {
enable = mkEnableOption "ZnapZend daemon";
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.znapzend ];
systemd.services = {
"znapzend" = {
description = "ZnapZend - ZFS Backup System";
after = [ "zfs.target" ];
path = with pkgs; [ znapzend zfs mbuffer openssh ];
script = ''
znapzend
'';
reload = ''
/bin/kill -HUP $MAINPID
'';
};
};
};
}

View File

@ -0,0 +1,123 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.awstats;
package = pkgs.awstats;
in
{
options.services.awstats = {
enable = mkOption {
type = types.bool;
default = cfg.service.enable;
description = ''
Enable the awstats program (but not service).
Currently only simple httpd (Apache) configs are supported,
and awstats plugins may not work correctly.
'';
};
vardir = mkOption {
type = types.path;
default = "/var/lib/awstats";
description = "The directory where variable awstats data will be stored.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = "Extra configuration to be appendend to awstats.conf.";
};
updateAt = mkOption {
type = types.nullOr types.string;
default = null;
example = "hourly";
description = ''
Specification of the time at which awstats will get updated.
(in the format described by <citerefentry>
<refentrytitle>systemd.time</refentrytitle>
<manvolnum>5</manvolnum></citerefentry>)
'';
};
service = {
enable = mkOption {
type = types.bool;
default = false;
description = ''Enable the awstats web service. This switches on httpd.'';
};
urlPrefix = mkOption {
type = types.string;
default = "/awstats";
description = "The URL prefix under which the awstats service appears.";
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ package.bin ];
/* TODO:
- heed config.services.httpd.logPerVirtualHost, etc.
- Can't AllowToUpdateStatsFromBrowser, as CGI scripts don't have permission
to read the logs, and our httpd config apparently doesn't an option for that.
*/
environment.etc."awstats/awstats.conf".source = pkgs.runCommand "awstats.conf"
{ preferLocalBuild = true; }
( let
cfg-httpd = config.services.httpd;
logFormat =
if cfg-httpd.logFormat == "combined" then "1" else
if cfg-httpd.logFormat == "common" then "4" else
throw "awstats service doesn't support Apache log format `${cfg-httpd.logFormat}`";
in
''
sed \
-e 's|^\(DirData\)=.*$|\1="${cfg.vardir}"|' \
-e 's|^\(DirIcons\)=.*$|\1="icons"|' \
-e 's|^\(CreateDirDataIfNotExists\)=.*$|\1=1|' \
-e 's|^\(SiteDomain\)=.*$|\1="${cfg-httpd.hostName}"|' \
-e 's|^\(LogFile\)=.*$|\1="${cfg-httpd.logDir}/access_log"|' \
-e 's|^\(LogFormat\)=.*$|\1=${logFormat}|' \
< '${package.out}/wwwroot/cgi-bin/awstats.model.conf' > "$out"
echo '${cfg.extraConfig}' >> "$out"
'');
# The httpd sub-service showing awstats.
services.httpd.enable = mkIf cfg.service.enable true;
services.httpd.extraSubservices = mkIf cfg.service.enable [ { function = { serverInfo, ... }: {
extraConfig =
''
Alias ${cfg.service.urlPrefix}/classes "${package.out}/wwwroot/classes/"
Alias ${cfg.service.urlPrefix}/css "${package.out}/wwwroot/css/"
Alias ${cfg.service.urlPrefix}/icons "${package.out}/wwwroot/icon/"
ScriptAlias ${cfg.service.urlPrefix}/ "${package.out}/wwwroot/cgi-bin/"
<Directory "${package.out}/wwwroot">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>
'';
startupScript =
let
inherit (serverInfo.serverConfig) user group;
in pkgs.writeScript "awstats_startup.sh"
''
mkdir -p '${cfg.vardir}'
chown '${user}:${group}' '${cfg.vardir}'
'';
};}];
systemd.services.awstats-update = mkIf (cfg.updateAt != null) {
description = "awstats log collector";
script = "exec '${package.bin}/bin/awstats' -update -config=awstats.conf";
startAt = cfg.updateAt;
};
};
}

View File

@ -98,8 +98,8 @@ in
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.dovecot22; default = pkgs.dovecot;
defaultText = "pkgs.dovecot22"; defaultText = "pkgs.dovecot";
description = "Dovecot package to use."; description = "Dovecot package to use.";
}; };

View File

@ -104,6 +104,7 @@ in {
systemd.services.dspam = { systemd.services.dspam = {
description = "dspam spam filtering daemon"; description = "dspam spam filtering daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "postgresql.service" ];
restartTriggers = [ cfgfile ]; restartTriggers = [ cfgfile ];
serviceConfig = { serviceConfig = {
@ -114,7 +115,7 @@ in {
RuntimeDirectoryMode = optional (cfg.domainSocket == defaultSock) "0750"; RuntimeDirectoryMode = optional (cfg.domainSocket == defaultSock) "0750";
PermissionsStartOnly = true; PermissionsStartOnly = true;
# DSPAM segfaults on just about every error # DSPAM segfaults on just about every error
Restart = "on-failure"; Restart = "on-abort";
RestartSec = "1s"; RestartSec = "1s";
}; };

View File

@ -12,9 +12,9 @@ with lib;
sendmailSetuidWrapper = mkOption { sendmailSetuidWrapper = mkOption {
default = null; default = null;
internal = true;
description = '' description = ''
Configuration for the sendmail setuid wrwapper (like an element of Configuration for the sendmail setuid wapper.
security.setuidOwners)";
''; '';
}; };

View File

@ -27,7 +27,7 @@ let
mainCf = mainCf =
'' ''
compatibility_level = 2 compatibility_level = 9999
mail_owner = ${user} mail_owner = ${user}
default_privs = nobody default_privs = nobody

View File

@ -79,6 +79,11 @@ in
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
preStart = ''
# There should be only one autofs service managed by systemd, so this should be safe.
rm -f /tmp/autofs-running
'';
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}"; ExecStart = "${pkgs.autofs5}/sbin/automount ${if cfg.debug then "-d" else ""} -f -t ${builtins.toString cfg.timeout} ${autoMaster} ${if cfg.debug then "-l7" else ""}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";

View File

@ -114,6 +114,7 @@ in {
}) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf); }) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf);
serviceConfig = { serviceConfig = {
Type = "notify";
ExecStart = "${pkgs.etcd}/bin/etcd"; ExecStart = "${pkgs.etcd}/bin/etcd";
User = "etcd"; User = "etcd";
PermissionsStartOnly = true; PermissionsStartOnly = true;

View File

@ -206,12 +206,6 @@ in {
description = "Gitlab database user."; description = "Gitlab database user.";
}; };
emailFrom = mkOption {
type = types.str;
default = "example@example.org";
description = "The source address for emails sent by gitlab.";
};
host = mkOption { host = mkOption {
type = types.str; type = types.str;
default = config.networking.hostName; default = config.networking.hostName;
@ -328,7 +322,7 @@ in {
Group = cfg.group; Group = cfg.group;
TimeoutSec = "300"; TimeoutSec = "300";
WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab"; WorkingDirectory = "${cfg.packages.gitlab}/share/gitlab";
ExecStart="${bundler}/bin/bundle exec \"sidekiq -q post_receive -q mailer -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.statePath}/tmp/sidekiq.pid\""; ExecStart="${bundler}/bin/bundle exec \"sidekiq -q post_receive -q mailers -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e production -P ${cfg.statePath}/tmp/sidekiq.pid\"";
}; };
}; };

View File

@ -0,0 +1,68 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mantisbt;
freshInstall = cfg.extraConfig == "";
# combined code+config directory
mantisbt = let
config_inc = pkgs.writeText "config_inc.php" ("<?php\n" + cfg.extraConfig);
src = pkgs.fetchurl {
url = "mirror://sourceforge/mantisbt/${name}.tar.gz";
sha256 = "1pl6xn793p3mxc6ibpr2bhg85vkdlcf57yk7pfc399g47l8x4508";
};
name = "mantisbt-1.2.19";
in
# We have to copy every time; otherwise config won't be found.
pkgs.runCommand name
{ preferLocalBuild = true; allowSubstitutes = false; }
(''
mkdir -p "$out"
cd "$out"
tar -xf '${src}' --strip-components=1
ln -s '${config_inc}' config_inc.php
''
+ lib.optionalString (!freshInstall) "rm -r admin/"
);
in
{
options.services.mantisbt = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Enable the mantisbt web service.
This switches on httpd with PHP and database.
'';
};
urlPrefix = mkOption {
type = types.string;
default = "/mantisbt";
description = "The URL prefix under which the mantisbt service appears.";
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
The contents of config_inc.php, without leading &lt;?php.
If left empty, the admin directory will be accessible.
'';
};
};
config = mkIf cfg.enable {
services.mysql.enable = true;
services.httpd.enable = true;
services.httpd.enablePHP = true;
# The httpd sub-service showing mantisbt.
services.httpd.extraSubservices = [ { function = { ... }: {
extraConfig =
''
Alias ${cfg.urlPrefix} "${mantisbt}"
'';
};}];
};
}

View File

@ -39,7 +39,7 @@ let
build-users-group = nixbld build-users-group = nixbld
build-max-jobs = ${toString (cfg.maxJobs)} build-max-jobs = ${toString (cfg.maxJobs)}
build-cores = ${toString (cfg.buildCores)} build-cores = ${toString (cfg.buildCores)}
build-use-chroot = ${if cfg.useChroot then "true" else "false"} build-use-chroot = ${if (builtins.isBool cfg.useChroot) then (if cfg.useChroot then "true" else "false") else cfg.useChroot}
build-chroot-dirs = ${toString cfg.chrootDirs} /bin/sh=${sh} $(echo $extraPaths) build-chroot-dirs = ${toString cfg.chrootDirs} /bin/sh=${sh} $(echo $extraPaths)
binary-caches = ${toString cfg.binaryCaches} binary-caches = ${toString cfg.binaryCaches}
trusted-binary-caches = ${toString cfg.trustedBinaryCaches} trusted-binary-caches = ${toString cfg.trustedBinaryCaches}
@ -99,7 +99,7 @@ in
}; };
useChroot = mkOption { useChroot = mkOption {
type = types.bool; type = types.either types.bool (types.enum ["relaxed"]);
default = false; default = false;
description = " description = "
If set, Nix will perform builds in a chroot-environment that it If set, Nix will perform builds in a chroot-environment that it
@ -257,13 +257,11 @@ in
type = types.bool; type = types.bool;
default = true; default = true;
description = '' description = ''
If enabled, Nix will only download binaries from binary If enabled (the default), Nix will only download binaries from binary caches if
caches if they are cryptographically signed with any of the they are cryptographically signed with any of the keys listed in
keys listed in <option>nix.binaryCachePublicKeys</option>. If disabled, signatures are neither
<option>nix.binaryCachePublicKeys</option>. If disabled (the required nor checked, so it's strongly recommended that you use only
default), signatures are neither required nor checked, so trustworthy caches and https to prevent man-in-the-middle attacks.
it's strongly recommended that you use only trustworthy
caches and https to prevent man-in-the-middle attacks.
''; '';
}; };

View File

@ -6,12 +6,16 @@ let
cfg = config.services.octoprint; cfg = config.services.octoprint;
cfgUpdate = pkgs.writeText "octoprint-config.yaml" (builtins.toJSON { baseConfig = {
plugins.cura.cura_engine = "${pkgs.curaengine}/bin/CuraEngine"; plugins.cura.cura_engine = "${pkgs.curaengine}/bin/CuraEngine";
server.host = cfg.host; server.host = cfg.host;
server.port = cfg.port; server.port = cfg.port;
webcam.ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg"; webcam.ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg";
}); };
fullConfig = recursiveUpdate cfg.extraConfig baseConfig;
cfgUpdate = pkgs.writeText "octoprint-config.yaml" (builtins.toJSON fullConfig);
pluginsEnv = pkgs.python.buildEnv.override { pluginsEnv = pkgs.python.buildEnv.override {
extraLibs = cfg.plugins pkgs.octoprint-plugins; extraLibs = cfg.plugins pkgs.octoprint-plugins;
@ -62,13 +66,18 @@ in
}; };
plugins = mkOption { plugins = mkOption {
#type = types.functionTo (types.listOf types.package);
default = plugins: []; default = plugins: [];
defaultText = "plugins: []"; defaultText = "plugins: []";
example = literalExample "plugins: [ m3d-fio ]"; example = literalExample "plugins: [ m3d-fio ]";
description = "Additional plugins."; description = "Additional plugins.";
}; };
extraConfig = mkOption {
type = types.attrs;
default = {};
description = "Extra options which are added to OctoPrint's YAML configuration file.";
};
}; };
}; };

View File

@ -87,7 +87,7 @@ in {
staticRootPath = mkOption { staticRootPath = mkOption {
description = "Root path for static assets."; description = "Root path for static assets.";
default = "${cfg.package.out}/share/grafana/public"; default = "${cfg.package}/share/grafana/public";
type = types.str; type = types.str;
}; };

View File

@ -51,7 +51,13 @@ let
''; '';
carbonEnv = { carbonEnv = {
PYTHONPATH = "${pkgs.python27Packages.carbon}/lib/python2.7/site-packages"; PYTHONPATH = let
cenv = pkgs.python.buildEnv.override {
extraLibs = [ pkgs.python27Packages.carbon ];
};
cenvPack = "${cenv}/${pkgs.python.sitePackages}";
# opt/graphite/lib contains twisted.plugins.carbon-cache
in "${cenvPack}/opt/graphite/lib:${cenvPack}";
GRAPHITE_ROOT = dataDir; GRAPHITE_ROOT = dataDir;
GRAPHITE_CONF_DIR = configDir; GRAPHITE_CONF_DIR = configDir;
GRAPHITE_STORAGE_DIR = dataDir; GRAPHITE_STORAGE_DIR = dataDir;
@ -445,10 +451,21 @@ in {
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
path = [ pkgs.perl ]; path = [ pkgs.perl ];
environment = { environment = {
PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages"; PYTHONPATH = let
penv = pkgs.python.buildEnv.override {
extraLibs = [
pkgs.python27Packages.graphite_web
pkgs.python27Packages.pysqlite
];
};
penvPack = "${penv}/${pkgs.python.sitePackages}";
# opt/graphite/webapp contains graphite/settings.py
# explicitly adding pycairo in path because it cannot be imported via buildEnv
in "${penvPack}/opt/graphite/webapp:${penvPack}:${pkgs.pycairo}/${pkgs.python.sitePackages}";
DJANGO_SETTINGS_MODULE = "graphite.settings"; DJANGO_SETTINGS_MODULE = "graphite.settings";
GRAPHITE_CONF_DIR = configDir; GRAPHITE_CONF_DIR = configDir;
GRAPHITE_STORAGE_DIR = dataDir; GRAPHITE_STORAGE_DIR = dataDir;
LD_LIBRARY_PATH = "${pkgs.cairo}/lib";
}; };
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = ''
@ -486,9 +503,11 @@ in {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment = { environment = {
PYTHONPATH = PYTHONPATH = let
"${cfg.api.package}/lib/python2.7/site-packages:" + aenv = pkgs.python.buildEnv.override {
concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders; extraLibs = [ cfg.api.package pkgs.cairo ] ++ cfg.api.finders;
};
in "${aenv}/${pkgs.python.sitePackages}";
GRAPHITE_API_CONFIG = graphiteApiConfig; GRAPHITE_API_CONFIG = graphiteApiConfig;
LD_LIBRARY_PATH = "${pkgs.cairo}/lib"; LD_LIBRARY_PATH = "${pkgs.cairo}/lib";
}; };

View File

@ -30,7 +30,7 @@ in
user = mkOption { user = mkOption {
type = types.string; type = types.string;
default = "ircd"; default = "bird";
description = '' description = ''
BIRD Internet Routing Daemon user. BIRD Internet Routing Daemon user.
''; '';
@ -38,7 +38,7 @@ in
group = mkOption { group = mkOption {
type = types.string; type = types.string;
default = "ircd"; default = "bird";
description = '' description = ''
BIRD Internet Routing Daemon group. BIRD Internet Routing Daemon group.
''; '';

View File

@ -5,13 +5,17 @@ let
apparmorEnabled = config.security.apparmor.enable; apparmorEnabled = config.security.apparmor.enable;
dnscrypt-proxy = pkgs.dnscrypt-proxy; dnscrypt-proxy = pkgs.dnscrypt-proxy;
cfg = config.services.dnscrypt-proxy; cfg = config.services.dnscrypt-proxy;
resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"; resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
localAddress = "${cfg.localAddress}:${toString cfg.localPort}"; localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
daemonArgs = daemonArgs =
[ "--local-address=${localAddress}" [ "--local-address=${localAddress}"
(optionalString cfg.tcpOnly "--tcp-only") (optionalString cfg.tcpOnly "--tcp-only")
(optionalString cfg.ephemeralKeys "-E")
] ]
++ resolverArgs; ++ resolverArgs;
resolverArgs = if (cfg.customResolver != null) resolverArgs = if (cfg.customResolver != null)
then then
[ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}" [ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}"
@ -27,43 +31,63 @@ in
{ {
options = { options = {
services.dnscrypt-proxy = { services.dnscrypt-proxy = {
enable = mkEnableOption '' enable = mkEnableOption "dnscrypt-proxy" // { description = ''
Enable dnscrypt-proxy. The proxy relays regular DNS queries to a Whether to enable the DNSCrypt client proxy. The proxy relays
DNSCrypt enabled upstream resolver. The traffic between the DNS queries to a DNSCrypt enabled upstream resolver. The traffic
client and the upstream resolver is encrypted and authenticated, between the client and the upstream resolver is encrypted and
which may mitigate the risk of MITM attacks and third-party authenticated, mitigating the risk of MITM attacks and third-party
snooping (assuming the upstream is trustworthy). snooping (assuming the upstream is trustworthy).
'';
Enabling this option does not alter the system nameserver; to relay
local queries, prepend <literal>127.0.0.1</literal> to
<option>networking.nameservers</option>.
The recommended configuration is to run DNSCrypt proxy as a forwarder
for a caching DNS client, as in
<programlisting>
{
services.dnscrypt-proxy.enable = true;
services.dnscrypt-proxy.localPort = 43;
services.dnsmasq.enable = true;
services.dnsmasq.servers = [ "127.0.0.1#43" ];
services.dnsmasq.resolveLocalQueries = true; # this is the default
}
</programlisting>
''; };
localAddress = mkOption { localAddress = mkOption {
default = "127.0.0.1"; default = "127.0.0.1";
type = types.string; type = types.string;
description = '' description = ''
Listen for DNS queries on this address. Listen for DNS queries to relay on this address. The only reason to
change this from its default value is to proxy queries on behalf
of other machines (typically on the local network).
''; '';
}; };
localPort = mkOption { localPort = mkOption {
default = 53; default = 53;
type = types.int; type = types.int;
description = '' description = ''
Listen on this port. Listen for DNS queries to relay on this port. The default value
assumes that the DNSCrypt proxy should relay DNS queries directly.
When running as a forwarder for another DNS client, set this option
to a different value; otherwise leave the default.
''; '';
}; };
resolverName = mkOption { resolverName = mkOption {
default = "opendns"; default = "dnscrypt.eu-nl";
type = types.nullOr types.string; type = types.nullOr types.string;
description = '' description = ''
The name of the upstream DNSCrypt resolver to use. See The name of the upstream DNSCrypt resolver to use. See
<literal>${resolverListFile}</literal> for alternative resolvers <filename>${resolverListFile}</filename> for alternative resolvers.
(e.g., if you are concerned about logging and/or server The default resolver is located in Holland, supports DNS security
location). extensions, and claims to not keep logs.
''; '';
}; };
customResolver = mkOption { customResolver = mkOption {
default = null; default = null;
description = '' description = ''
Use a resolver not listed in the upstream list (e.g., Use an unlisted resolver (e.g., a private DNSCrypt provider). For
a private DNSCrypt provider). For advanced users only. advanced users only. If specified, this option takes precedence.
If specified, this option takes precedence.
''; '';
type = types.nullOr (types.submodule ({ ... }: { options = { type = types.nullOr (types.submodule ({ ... }: { options = {
address = mkOption { address = mkOption {
@ -80,20 +104,31 @@ in
type = types.str; type = types.str;
description = "Provider fully qualified domain name"; description = "Provider fully qualified domain name";
example = "2.dnscrypt-cert.opendns.com"; example = "2.dnscrypt-cert.opendns.com";
}; };
key = mkOption { key = mkOption {
type = types.str; type = types.str;
description = "Provider public key"; description = "Provider public key";
example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79"; example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79";
}; }; })); };
}; }));
}; };
tcpOnly = mkOption { tcpOnly = mkOption {
default = false; default = false;
type = types.bool; type = types.bool;
description = '' description = ''
Force sending encrypted DNS queries to the upstream resolver Force sending encrypted DNS queries to the upstream resolver over
over TCP instead of UDP (on port 443). Enabling this option may TCP instead of UDP (on port 443). Use only if the UDP port is blocked.
help circumvent filtering, but should not be used otherwise. '';
};
ephemeralKeys = mkOption {
default = false;
type = types.bool;
description = ''
Compute a new key pair for every query. Enabling this option
increases CPU usage, but makes it more difficult for the upstream
resolver to track your usage of their service across IP addresses.
The default is to re-use the public key pair for all queries, making
tracking trivial.
''; '';
}; };
}; };
@ -130,16 +165,20 @@ in
${pkgs.xz}/lib/liblzma.so.* mr, ${pkgs.xz}/lib/liblzma.so.* mr,
${pkgs.libgcrypt}/lib/libgcrypt.so.* mr, ${pkgs.libgcrypt}/lib/libgcrypt.so.* mr,
${pkgs.libgpgerror}/lib/libgpg-error.so.* mr, ${pkgs.libgpgerror}/lib/libgpg-error.so.* mr,
${pkgs.libcap}/lib/libcap.so.* mr,
${pkgs.lz4}/lib/liblz4.so.* mr,
${pkgs.attr}/lib/libattr.so.* mr,
${resolverListFile} r, ${resolverListFile} r,
} }
'')); ''));
users.extraUsers.dnscrypt-proxy = { users.users.dnscrypt-proxy = {
uid = config.ids.uids.dnscrypt-proxy;
description = "dnscrypt-proxy daemon user"; description = "dnscrypt-proxy daemon user";
isSystemUser = true;
group = "dnscrypt-proxy";
}; };
users.extraGroups.dnscrypt-proxy.gid = config.ids.gids.dnscrypt-proxy; users.groups.dnscrypt-proxy = {};
systemd.sockets.dnscrypt-proxy = { systemd.sockets.dnscrypt-proxy = {
description = "dnscrypt-proxy listening socket"; description = "dnscrypt-proxy listening socket";
@ -152,16 +191,21 @@ in
systemd.services.dnscrypt-proxy = { systemd.services.dnscrypt-proxy = {
description = "dnscrypt-proxy daemon"; description = "dnscrypt-proxy daemon";
after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service"; after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service"; requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service";
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
NonBlocking = "true"; NonBlocking = "true";
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}"; ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
User = "dnscrypt-proxy"; User = "dnscrypt-proxy";
Group = "dnscrypt-proxy"; Group = "dnscrypt-proxy";
PrivateTmp = true; PrivateTmp = true;
PrivateDevices = true; PrivateDevices = true;
ProtectHome = true;
}; };
}; };
}; };

View File

@ -338,7 +338,7 @@ in
}; };
networking.firewall.allowPing = mkOption { networking.firewall.allowPing = mkOption {
default = false; default = true;
type = types.bool; type = types.bool;
description = description =
'' ''

View File

@ -10,9 +10,10 @@ let
extip = "EXTIP=\$(${pkgs.curl}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')"; extip = "EXTIP=\$(${pkgs.curl}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
toOneZero = b: if b then "1" else "0"; toYesNo = b: if b then "yes" else "no";
mkEndpointOpt = name: addr: port: { mkEndpointOpt = name: addr: port: {
enable = mkEnableOption name;
name = mkOption { name = mkOption {
type = types.str; type = types.str;
default = name; default = name;
@ -63,9 +64,9 @@ let
} // mkEndpointOpt name "127.0.0.1" 0; } // mkEndpointOpt name "127.0.0.1" 0;
i2pdConf = pkgs.writeText "i2pd.conf" '' i2pdConf = pkgs.writeText "i2pd.conf" ''
ipv6 = ${toOneZero cfg.enableIPv6} ipv6 = ${toYesNo cfg.enableIPv6}
notransit = ${toOneZero cfg.notransit} notransit = ${toYesNo cfg.notransit}
floodfill = ${toOneZero cfg.floodfill} floodfill = ${toYesNo cfg.floodfill}
${if isNull cfg.port then "" else "port = ${toString cfg.port}"} ${if isNull cfg.port then "" else "port = ${toString cfg.port}"}
${flip concatMapStrings ${flip concatMapStrings
(collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto) (collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto)
@ -73,6 +74,7 @@ let
[${proto.name}] [${proto.name}]
address = ${proto.address} address = ${proto.address}
port = ${toString proto.port} port = ${toString proto.port}
enabled = ${toYesNo proto.enable}
'') '')
} }
''; '';

View File

@ -64,8 +64,7 @@ in
systemd.services.iodined = { systemd.services.iodined = {
description = "iodine, ip over dns daemon"; description = "iodine, ip over dns daemon";
after = [ "network.target" ]; wantedBy = [ "ip-up.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig.ExecStart = "${pkgs.iodine}/sbin/iodined -f -u ${iodinedUser} ${cfg.extraConfig} ${cfg.ip} ${cfg.domain}"; serviceConfig.ExecStart = "${pkgs.iodine}/sbin/iodined -f -u ${iodinedUser} ${cfg.extraConfig} ${cfg.ip} ${cfg.domain}";
}; };

View File

@ -0,0 +1,75 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.mjpg-streamer;
in {
options = {
services.mjpg-streamer = {
enable = mkEnableOption "mjpg-streamer webcam streamer";
inputPlugin = mkOption {
type = types.str;
default = "input_uvc.so";
description = ''
Input plugin. See plugins documentation for more information.
'';
};
outputPlugin = mkOption {
type = types.str;
default = "output_http.so -w @www@ -n -p 5050";
description = ''
Output plugin. <literal>@www@</literal> is substituted for default mjpg-streamer www directory.
See plugins documentation for more information.
'';
};
user = mkOption {
type = types.str;
default = "mjpg-streamer";
description = "mjpg-streamer user name.";
};
group = mkOption {
type = types.str;
default = "video";
description = "mjpg-streamer group name.";
};
};
};
config = mkIf cfg.enable {
users.extraUsers = optional (cfg.user == "mjpg-streamer") {
name = "mjpg-streamer";
uid = config.ids.uids.mjpg-streamer;
group = cfg.group;
};
systemd.services.mjpg-streamer = {
description = "mjpg-streamer webcam streamer";
wantedBy = [ "multi-user.target" ];
serviceConfig.User = cfg.user;
serviceConfig.Group = cfg.group;
script = ''
IPLUGIN="${cfg.inputPlugin}"
OPLUGIN="${cfg.outputPlugin}"
OPLUGIN="''${OPLUGIN//@www@/${pkgs.mjpg-streamer}/share/mjpg-streamer/www}"
exec ${pkgs.mjpg-streamer}/bin/mjpg_streamer -i "$IPLUGIN" -o "$OPLUGIN"
'';
};
};
}

View File

@ -346,7 +346,7 @@ in
type = types.bool; type = types.bool;
default = true; default = true;
description = '' description = ''
Wheter NSD should answer VERSION.BIND and VERSION.SERVER CHAOS class queries. Whether NSD should answer VERSION.BIND and VERSION.SERVER CHAOS class queries.
''; '';
}; };
@ -378,7 +378,7 @@ in
type = types.bool; type = types.bool;
default = true; default = true;
description = '' description = ''
Wheter to listen on IPv4 connections. Whether to listen on IPv4 connections.
''; '';
}; };
@ -394,7 +394,7 @@ in
type = types.bool; type = types.bool;
default = true; default = true;
description = '' description = ''
Wheter to listen on IPv6 connections. Whether to listen on IPv6 connections.
''; '';
}; };
@ -434,7 +434,7 @@ in
type = types.bool; type = types.bool;
default = pkgs.stdenv.isLinux; default = pkgs.stdenv.isLinux;
description = '' description = ''
Wheter to enable SO_REUSEPORT on all used sockets. This lets multiple Whether to enable SO_REUSEPORT on all used sockets. This lets multiple
processes bind to the same port. This speeds up operation especially processes bind to the same port. This speeds up operation especially
if the server count is greater than one and makes fast restarts less if the server count is greater than one and makes fast restarts less
prone to fail prone to fail
@ -445,7 +445,7 @@ in
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
Wheter if this server will be a root server (a DNS root server, you Whether this server will be a root server (a DNS root server, you
usually don't want that). usually don't want that).
''; '';
}; };
@ -524,7 +524,7 @@ in
type = types.bool; type = types.bool;
default = true; default = true;
description = '' description = ''
Wheter to check mtime of all zone files on start and sighup. Whether to check mtime of all zone files on start and sighup.
''; '';
}; };

View File

@ -35,12 +35,27 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.pythonPackages.radicale ]; environment.systemPackages = [ pkgs.pythonPackages.radicale ];
users.extraUsers = singleton
{ name = "radicale";
uid = config.ids.uids.radicale;
description = "radicale user";
home = "/var/lib/radicale";
createHome = true;
};
users.extraGroups = singleton
{ name = "radicale";
gid = config.ids.gids.radicale;
};
systemd.services.radicale = { systemd.services.radicale = {
description = "A Simple Calendar and Contact Server"; description = "A Simple Calendar and Contact Server";
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -d"; script = "${pkgs.pythonPackages.radicale}/bin/radicale -C ${confFile} -d";
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.User = "radicale";
serviceConfig.Group = "radicale";
}; };
}; };
} }

View File

@ -263,7 +263,7 @@ in
serviceConfig = serviceConfig =
{ ExecStart = { ExecStart =
"${cfgc.package}/sbin/sshd " + (optionalString cfg.startWhenNeeded "-i ") + "${cfgc.package}/bin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}"; "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
KillMode = "process"; KillMode = "process";
} // (if cfg.startWhenNeeded then { } // (if cfg.startWhenNeeded then {

View File

@ -113,7 +113,7 @@ in
''; '';
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.unbound}/sbin/unbound -d -c ${stateDir}/unbound.conf"; ExecStart = "${pkgs.unbound}/bin/unbound -d -c ${stateDir}/unbound.conf";
ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random"; ExecStopPost="${pkgs.utillinux}/bin/umount ${stateDir}/dev/random";
}; };
}; };

View File

@ -85,6 +85,9 @@ let
ssl_enable=YES ssl_enable=YES
rsa_cert_file=${cfg.rsaCertFile} rsa_cert_file=${cfg.rsaCertFile}
''} ''}
${optionalString (cfg.rsaKeyFile != null) ''
rsa_private_key_file=${cfg.rsaKeyFile}
''}
${optionalString (cfg.userlistFile != null) '' ${optionalString (cfg.userlistFile != null) ''
userlist_file=${cfg.userlistFile} userlist_file=${cfg.userlistFile}
''} ''}
@ -147,6 +150,12 @@ in
description = "RSA certificate file."; description = "RSA certificate file.";
}; };
rsaKeyFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "RSA private key file.";
};
anonymousUmask = mkOption { anonymousUmask = mkOption {
type = types.string; type = types.string;
default = "077"; default = "077";

View File

@ -238,7 +238,8 @@ in
example = literalExample "[ pkgs.splix ]"; example = literalExample "[ pkgs.splix ]";
description = '' description = ''
CUPS drivers to use. Drivers provided by CUPS, cups-filters, Ghostscript CUPS drivers to use. Drivers provided by CUPS, cups-filters, Ghostscript
and Samba are added unconditionally. and Samba are added unconditionally. For adding Gutenprint, see
<literal>gutenprint</literal>.
''; '';
}; };
@ -310,7 +311,9 @@ in
[ ! -e "/var/lib/cups/$i" ] && ln -s "${rootdir}/etc/cups/$i" "/var/lib/cups/$i" [ ! -e "/var/lib/cups/$i" ] && ln -s "${rootdir}/etc/cups/$i" "/var/lib/cups/$i"
done done
${optionalString cfg.gutenprint '' ${optionalString cfg.gutenprint ''
${gutenprint}/bin/cups-genppdupdate -p /etc/cups/ppd if [ -d /var/lib/cups/ppd ]; then
${gutenprint}/bin/cups-genppdupdate -p /var/lib/cups/ppd
fi
''} ''}
''; '';
}; };

View File

@ -46,7 +46,7 @@ in
}; };
systemd.services.kdc = { systemd.services.kdc = {
description = "Kerberos Domain Controller daemon"; description = "Key Distribution Center daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
preStart = '' preStart = ''
mkdir -m 0755 -p ${stateDir} mkdir -m 0755 -p ${stateDir}
@ -55,7 +55,7 @@ in
}; };
systemd.services.kpasswdd = { systemd.services.kpasswdd = {
description = "Kerberos Domain Controller daemon"; description = "Kerberos Password Changing daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
script = "${heimdal}/sbin/kpasswdd"; script = "${heimdal}/sbin/kpasswdd";
}; };

View File

@ -128,6 +128,7 @@ in
${pkgs.c-ares}/lib/libcares*.so* mr, ${pkgs.c-ares}/lib/libcares*.so* mr,
${pkgs.libcap}/lib/libcap*.so* mr, ${pkgs.libcap}/lib/libcap*.so* mr,
${pkgs.attr}/lib/libattr*.so* mr, ${pkgs.attr}/lib/libattr*.so* mr,
${pkgs.lz4}/lib/liblz4*.so* mr,
@{PROC}/sys/kernel/random/uuid r, @{PROC}/sys/kernel/random/uuid r,
@{PROC}/sys/vm/overcommit_memory r, @{PROC}/sys/vm/overcommit_memory r,

View File

@ -0,0 +1,78 @@
{ config, pkgs, lib, serverInfo, ... }:
let
inherit (pkgs) foswiki;
inherit (serverInfo.serverConfig) user group;
inherit (config) vardir;
in
{
options.vardir = lib.mkOption {
type = lib.types.path;
default = "/var/www/foswiki";
description = "The directory where variable foswiki data will be stored and served from.";
};
# TODO: this will probably need to be better customizable
extraConfig =
let httpd-conf = pkgs.runCommand "foswiki-httpd.conf"
{ preferLocalBuild = true; }
''
substitute '${foswiki}/foswiki_httpd_conf.txt' "$out" \
--replace /var/www/foswiki/ "${vardir}/"
'';
in
''
RewriteEngine on
RewriteRule /foswiki/(.*) ${vardir}/$1
<Directory "${vardir}">
Require all granted
</Directory>
Include ${httpd-conf}
<Directory "${vardir}/pub">
Options FollowSymlinks
</Directory>
'';
/** This handles initial setup and updates.
It will probably need some tweaking, maybe per-site. */
startupScript = pkgs.writeScript "foswiki_startup.sh" (
let storeLink = "${vardir}/package"; in
''
[ -e '${storeLink}' ] || needs_setup=1
mkdir -p '${vardir}'
cd '${vardir}'
ln -sf -T '${foswiki}' '${storeLink}'
if [ -n "$needs_setup" ]; then # do initial setup
mkdir -p bin lib
# setup most of data/ as copies only
cp -r '${foswiki}'/data '${vardir}/'
rm -r '${vardir}'/data/{System,mime.types}
ln -sr -t '${vardir}/data/' '${storeLink}'/data/{System,mime.types}
ln -sr '${storeLink}/locale' .
mkdir pub
ln -sr '${storeLink}/pub/System' pub/
mkdir templates
ln -sr '${storeLink}'/templates/* templates/
ln -sr '${storeLink}/tools' .
mkdir -p '${vardir}'/working/{logs,tmp}
ln -sr '${storeLink}/working/README' working/ # used to check dir validity
chown -R '${user}:${group}' .
chmod +w -R .
fi
# bin/* and lib/* shall always be overwritten, in case files are added
ln -srf '${storeLink}'/bin/* '${vardir}/bin/'
ln -srf '${storeLink}'/lib/* '${vardir}/lib/'
''
/* Symlinking bin/ one-by-one ensures that ${vardir}/lib/LocalSite.cfg
is used instead of ${foswiki}/... */
);
}

View File

@ -32,17 +32,27 @@ let
self = pythonPackages; self = pythonPackages;
}; };
json = builtins.toJSON { penv = python.buildEnv.override {
extraLibs = (c.pythonPackages or (self: [])) pythonPackages;
};
uwsgiCfg = {
uwsgi = uwsgi =
if c.type == "normal" if c.type == "normal"
then { then {
inherit plugins; inherit plugins;
} // removeAttrs c [ "type" "pythonPackages" ] } // removeAttrs c [ "type" "pythonPackages" ]
// optionalAttrs (python != null) { // optionalAttrs (python != null) {
pythonpath = "@PYTHONPATH@"; pythonpath = "${penv}/${python.sitePackages}";
env = (c.env or {}) // { env =
PATH = optionalString (c ? env.PATH) "${c.env.PATH}:" + "@PATH@"; # Argh, uwsgi expects list of key-values there instead of a dictionary.
}; let env' = c.env or [];
getPath =
x: if hasPrefix "PATH=" x
then substring (stringLength "PATH=") (stringLength x) x
else null;
oldPaths = filter (x: x != null) (map getPath env');
in env' ++ [ "PATH=${optionalString (oldPaths != []) "${last oldPaths}:"}${penv}/bin" ];
} }
else if c.type == "emperor" else if c.type == "emperor"
then { then {
@ -55,35 +65,7 @@ let
else throw "`type` attribute in UWSGI configuration should be either 'normal' or 'emperor'"; else throw "`type` attribute in UWSGI configuration should be either 'normal' or 'emperor'";
}; };
in in pkgs.writeTextDir "${name}.json" (builtins.toJSON uwsgiCfg);
if python == null || c.type != "normal"
then pkgs.writeTextDir "${name}.json" json
else pkgs.stdenv.mkDerivation {
name = "uwsgi-config";
inherit json;
passAsFile = [ "json" ];
nativeBuildInputs = [ pythonPackages.wrapPython ];
pythonInputs = (c.pythonPackages or (self: [])) pythonPackages;
buildCommand = ''
mkdir $out
declare -A pythonPathsSeen=()
program_PYTHONPATH=
program_PATH=
if [ -n "$pythonInputs" ]; then
for i in $pythonInputs; do
_addToPythonPath $i
done
fi
# A hack to replace "@PYTHONPATH@" with a JSON list
if [ -n "$program_PYTHONPATH" ]; then
program_PYTHONPATH="\"''${program_PYTHONPATH//:/\",\"}\""
fi
substitute $jsonPath $out/${name}.json \
--replace '"@PYTHONPATH@"' "[$program_PYTHONPATH]" \
--subst-var-by PATH "$program_PATH"
'';
};
in { in {

View File

@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.colord;
in {
options = {
services.colord = {
enable = mkEnableOption "colord, the color management daemon";
};
};
config = mkIf cfg.enable {
services.dbus.packages = [ pkgs.colord ];
services.udev.packages = [ pkgs.colord ];
environment.systemPackages = [ pkgs.colord ];
systemd.services.colord = {
description = "Manage, Install and Generate Color Profiles";
serviceConfig = {
Type = "dbus";
BusName = "org.freedesktop.ColorManager";
ExecStart = "${pkgs.colord}/libexec/colord";
PrivateTmp = true;
};
};
};
}

View File

@ -19,7 +19,7 @@ in
# E.g., if KDE is enabled, it supersedes xterm. # E.g., if KDE is enabled, it supersedes xterm.
imports = [ imports = [
./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./kde5.nix
./e19.nix ./gnome3.nix ./kodi.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix
]; ];
options = { options = {

View File

@ -4,9 +4,9 @@ with lib;
let let
e = pkgs.enlightenment;
xcfg = config.services.xserver; xcfg = config.services.xserver;
cfg = xcfg.desktopManager.e19; cfg = xcfg.desktopManager.enlightenment;
e19_enlightenment = pkgs.e19.enlightenment.override { set_freqset_setuid = true; };
GST_PLUGIN_PATH = lib.makeSearchPath "lib/gstreamer-1.0" [ GST_PLUGIN_PATH = lib.makeSearchPath "lib/gstreamer-1.0" [
pkgs.gst_all_1.gst-plugins-base pkgs.gst_all_1.gst-plugins-base
pkgs.gst_all_1.gst-plugins-good pkgs.gst_all_1.gst-plugins-good
@ -18,10 +18,10 @@ in
{ {
options = { options = {
services.xserver.desktopManager.e19.enable = mkOption { services.xserver.desktopManager.enlightenment.enable = mkOption {
default = false; default = false;
example = true; example = true;
description = "Enable the E19 desktop environment."; description = "Enable the Enlightenment desktop environment.";
}; };
}; };
@ -29,8 +29,8 @@ in
config = mkIf (xcfg.enable && cfg.enable) { config = mkIf (xcfg.enable && cfg.enable) {
environment.systemPackages = [ environment.systemPackages = [
pkgs.e19.efl pkgs.e19.evas pkgs.e19.emotion pkgs.e19.elementary e19_enlightenment e.efl e.evas e.emotion e.elementary e.enlightenment
pkgs.e19.terminology pkgs.e19.econnman e.terminology e.econnman
pkgs.xorg.xauth # used by kdesu pkgs.xorg.xauth # used by kdesu
pkgs.gtk # To get GTK+'s themes. pkgs.gtk # To get GTK+'s themes.
pkgs.tango-icon-theme pkgs.tango-icon-theme
@ -42,7 +42,7 @@ in
environment.pathsToLink = [ "/etc/enlightenment" "/etc/xdg" "/share/enlightenment" "/share/elementary" "/share/applications" "/share/locale" "/share/icons" "/share/themes" "/share/mime" "/share/desktop-directories" ]; environment.pathsToLink = [ "/etc/enlightenment" "/etc/xdg" "/share/enlightenment" "/share/elementary" "/share/applications" "/share/locale" "/share/icons" "/share/themes" "/share/mime" "/share/desktop-directories" ];
services.xserver.desktopManager.session = [ services.xserver.desktopManager.session = [
{ name = "E19"; { name = "Enlightenment";
start = '' start = ''
# Set GTK_DATA_PREFIX so that GTK+ can find the themes # Set GTK_DATA_PREFIX so that GTK+ can find the themes
export GTK_DATA_PREFIX=${config.system.path} export GTK_DATA_PREFIX=${config.system.path}
@ -53,17 +53,16 @@ in
export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}" export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"
# make available for D-BUS user services # make available for D-BUS user services
#export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}:${config.system.path}/share:${pkgs.e19.efl}/share #export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}:${config.system.path}/share:${e.efl}/share
# Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/ # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
${e19_enlightenment}/bin/enlightenment_start exec ${e.enlightenment}/bin/enlightenment_start
waitPID=$!
''; '';
}]; }];
security.setuidPrograms = [ "e19_freqset" ]; security.setuidPrograms = [ "e_freqset" ];
environment.etc = singleton environment.etc = singleton
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
@ -75,13 +74,13 @@ in
services.udisks2.enable = true; services.udisks2.enable = true;
services.upower.enable = config.powerManagement.enable; services.upower.enable = config.powerManagement.enable;
#services.dbus.packages = [ pkgs.efl ]; # dbus-1 folder is not in /etc but in /share, so needs fixing first services.dbus.packages = [ e.efl ];
systemd.user.services.efreet = systemd.user.services.efreet =
{ enable = true; { enable = true;
description = "org.enlightenment.Efreet"; description = "org.enlightenment.Efreet";
serviceConfig = serviceConfig =
{ ExecStart = "${pkgs.e19.efl}/bin/efreetd"; { ExecStart = "${e.efl}/bin/efreetd";
StandardOutput = "null"; StandardOutput = "null";
}; };
}; };
@ -90,7 +89,7 @@ in
{ enable = true; { enable = true;
description = "org.enlightenment.Ethumb"; description = "org.enlightenment.Ethumb";
serviceConfig = serviceConfig =
{ ExecStart = "${pkgs.e19.efl}/bin/ethumbd"; { ExecStart = "${e.efl}/bin/ethumbd";
StandardOutput = "null"; StandardOutput = "null";
}; };
}; };

View File

@ -128,6 +128,7 @@ in
++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm ++ lib.optional config.networking.networkmanager.enable kde5.plasma-nm
++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa ++ lib.optional config.hardware.pulseaudio.enable kde5.plasma-pa
++ lib.optional config.powerManagement.enable kde5.powerdevil ++ lib.optional config.powerManagement.enable kde5.powerdevil
++ lib.optional config.services.colord.enable kde5.colord-kde
++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ] ++ lib.optionals config.services.samba.enable [ kde5.kdenetwork-filesharing pkgs.samba ]
++ lib.optionals cfg.phonon.gstreamer.enable ++ lib.optionals cfg.phonon.gstreamer.enable

View File

@ -49,17 +49,6 @@ let
fi fi
''} ''}
${optionalString cfg.startGnuPGAgent ''
if test -z "$SSH_AUTH_SOCK"; then
# Restart this script as a child of the GnuPG agent.
exec "${pkgs.gnupg}/bin/gpg-agent" \
--enable-ssh-support --daemon \
--pinentry-program "${pkgs.pinentry}/bin/pinentry-gtk-2" \
--write-env-file "$HOME/.gpg-agent-info" \
"$0" "$sessionType"
fi
''}
# Handle being called by kdm. # Handle being called by kdm.
if test "''${1:0:1}" = /; then eval exec "$1"; fi if test "''${1:0:1}" = /; then eval exec "$1"; fi

View File

@ -10,13 +10,13 @@ in
imports = [ imports = [
./afterstep.nix ./afterstep.nix
./bspwm.nix ./bspwm.nix
./clfswm.nix
./compiz.nix ./compiz.nix
./dwm.nix ./dwm.nix
./exwm.nix ./exwm.nix
./fluxbox.nix ./fluxbox.nix
./herbstluftwm.nix ./herbstluftwm.nix
./i3.nix ./i3.nix
./jwm.nix
./metacity.nix ./metacity.nix
./openbox.nix ./openbox.nix
./notion.nix ./notion.nix

View File

@ -0,0 +1,25 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.xserver.windowManager.jwm;
in
{
###### interface
options = {
services.xserver.windowManager.jwm.enable = mkEnableOption "jwm";
};
###### implementation
config = mkIf cfg.enable {
services.xserver.windowManager.session = singleton {
name = "jwm";
start = ''
${pkgs.jwm}/bin/jwm &
waitPID=$!
'';
};
environment.systemPackages = [ pkgs.jwm ];
};
}

View File

@ -160,7 +160,7 @@ in
[ ''' [ '''
Identifier "Trackpoint Wheel Emulation" Identifier "Trackpoint Wheel Emulation"
MatchProduct "ThinkPad USB Keyboard with TrackPoint" MatchProduct "ThinkPad USB Keyboard with TrackPoint"
Option "EmulateWheel" "true Option "EmulateWheel" "true"
Option "EmulateWheelButton" "2" Option "EmulateWheelButton" "2"
Option "Emulate3Buttons" "false" Option "Emulate3Buttons" "false"
''' '''
@ -219,17 +219,6 @@ in
''; '';
}; };
startGnuPGAgent = mkOption {
type = types.bool;
default = false;
description = ''
Whether to start the GnuPG agent when you log in. The GnuPG agent
remembers private keys for you so that you don't have to type in
passphrases every time you make an SSH connection or sign/encrypt
data. Use <command>ssh-add</command> to add a key to the agent.
'';
};
startDbusSession = mkOption { startDbusSession = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
@ -444,14 +433,7 @@ in
in optional (driver != null) ({ inherit name; driverName = name; } // driver)); in optional (driver != null) ({ inherit name; driverName = name; } // driver));
assertions = assertions =
[ { assertion = !(config.programs.ssh.startAgent && cfg.startGnuPGAgent); [ { assertion = config.security.polkit.enable;
message =
''
The OpenSSH agent and GnuPG agent cannot be started both. Please
choose between programs.ssh.startAgent and services.xserver.startGnuPGAgent.
'';
}
{ assertion = config.security.polkit.enable;
message = "X11 requires Polkit to be enabled (security.polkit.enable = true)."; message = "X11 requires Polkit to be enabled (security.polkit.enable = true).";
} }
]; ];

View File

@ -33,19 +33,24 @@ with lib;
}; };
config = mkIf config.systemd.coredump.enable { config = mkMerge [
(mkIf config.systemd.coredump.enable {
environment.etc."systemd/coredump.conf".text = environment.etc."systemd/coredump.conf".text =
'' ''
[Coredump] [Coredump]
${config.systemd.coredump.extraConfig} ${config.systemd.coredump.extraConfig}
''; '';
# Have the kernel pass core dumps to systemd's coredump helper binary. # Have the kernel pass core dumps to systemd's coredump helper binary.
# From systemd's 50-coredump.conf file. See: # From systemd's 50-coredump.conf file. See:
# <https://github.com/systemd/systemd/blob/v218/sysctl.d/50-coredump.conf.in> # <https://github.com/systemd/systemd/blob/v218/sysctl.d/50-coredump.conf.in>
boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %p %u %g %s %t %e"; boot.kernel.sysctl."kernel.core_pattern" = "|${pkgs.systemd}/lib/systemd/systemd-coredump %p %u %g %s %t %e";
})
}; (mkIf (!config.systemd.coredump.enable) {
boot.kernel.sysctl."kernel.core_pattern" = mkDefault "core";
})
];
} }

View File

@ -58,6 +58,7 @@ let
# Add RAID mdadm tool. # Add RAID mdadm tool.
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm
copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
# Copy udev. # Copy udev.
copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd copy_bin_and_libs ${udev}/lib/systemd/systemd-udevd

View File

@ -93,7 +93,7 @@ let
config = { config = {
mountPoint = mkDefault name; mountPoint = mkDefault name;
device = mkIf (config.fsType == "tmpfs") (mkDefault config.fsType); device = mkIf (config.fsType == "tmpfs") (mkDefault config.fsType);
options = mkIf config.autoResize "x-nixos.autoresize"; options = mkIf config.autoResize [ "x-nixos.autoresize" ];
# -F needed to allow bare block device without partitions # -F needed to allow bare block device without partitions
formatOptions = mkIf ((builtins.substring 0 3 config.fsType) == "ext") (mkDefault "-F"); formatOptions = mkIf ((builtins.substring 0 3 config.fsType) == "ext") (mkDefault "-F");

View File

@ -882,10 +882,8 @@ in
optionalString hasBonds "options bonding max_bonds=0"; optionalString hasBonds "options bonding max_bonds=0";
boot.kernel.sysctl = { boot.kernel.sysctl = {
"net.net.ipv4.conf.all.promote_secondaries" = true;
"net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6); "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6);
"net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6); "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
"net.ipv4.conf.all_forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
"net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces); "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
} // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces) } // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces)
(i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)) (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))

View File

@ -12,4 +12,45 @@
cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/ cp -v ${pkgs.mdadm}/lib/udev/rules.d/*.rules $out/
''; '';
systemd.services.mdadm-shutdown = {
wantedBy = [ "final.target"];
after = [ "umount.target" ];
unitConfig = {
DefaultDependencies = false;
};
serviceConfig = {
Type = "oneshot";
ExecStart = ''${pkgs.mdadm}/bin/mdadm --wait-clean --scan'';
};
};
systemd.services."mdmon@" = {
description = "MD Metadata Monitor on /dev/%I";
unitConfig.DefaultDependencies = false;
serviceConfig = {
Type = "forking";
Environment = "IMSM_NO_PLATFORM=1";
ExecStart = ''${pkgs.mdadm}/bin/mdmon --offroot --takeover %I'';
KillMode = "none";
};
};
systemd.services."mdadm-grow-continue@" = {
description = "Manage MD Reshape on /dev/%I";
unitConfig.DefaultDependencies = false;
serviceConfig = {
ExecStart = ''${pkgs.mdadm}/bin/mdadm --grow --continue /dev/%I'';
StandardInput = "null";
StandardOutput = "null";
StandardError = "null";
KillMode = "none";
};
};
} }

View File

@ -40,7 +40,6 @@ let cfg = config.ec2; in
# Force udev to exit to prevent random "Device or resource busy # Force udev to exit to prevent random "Device or resource busy
# while trying to open /dev/xvda" errors from fsck. # while trying to open /dev/xvda" errors from fsck.
udevadm control --exit || true udevadm control --exit || true
kill -9 -1
''; '';
boot.initrd.network.enable = true; boot.initrd.network.enable = true;

View File

@ -0,0 +1,17 @@
--- a/waagent 2016-03-12 09:58:15.728088851 +0200
+++ a/waagent 2016-03-12 09:58:43.572680025 +0200
@@ -6173,10 +6173,10 @@
Log("MAC address: " + ":".join(["%02X" % Ord(a) for a in mac]))
# Consume Entropy in ACPI table provided by Hyper-V
- try:
- SetFileContents("/dev/random", GetFileContents("/sys/firmware/acpi/tables/OEM0"))
- except:
- pass
+ #try:
+ # SetFileContents("/dev/random", GetFileContents("/sys/firmware/acpi/tables/OEM0"))
+ #except:
+ # pass
Log("Probing for Azure environment.")
self.Endpoint = self.DoDhcpWork()

View File

@ -14,6 +14,9 @@ let
rev = "1b3a8407a95344d9d12a2a377f64140975f1e8e4"; rev = "1b3a8407a95344d9d12a2a377f64140975f1e8e4";
sha256 = "10byzvmpgrmr4d5mdn2kq04aapqb3sgr1admk13wjmy5cd6bwd2x"; sha256 = "10byzvmpgrmr4d5mdn2kq04aapqb3sgr1admk13wjmy5cd6bwd2x";
}; };
patches = [ ./azure-agent-entropy.patch ];
buildInputs = [ makeWrapper python pythonPackages.wrapPython ]; buildInputs = [ makeWrapper python pythonPackages.wrapPython ];
runtimeDeps = [ findutils gnugrep gawk coreutils openssl openssh runtimeDeps = [ findutils gnugrep gawk coreutils openssl openssh
nettools # for hostname nettools # for hostname
@ -54,9 +57,15 @@ in
###### interface ###### interface
options.virtualisation.azure.agent.enable = mkOption { options.virtualisation.azure.agent = {
default = false; enable = mkOption {
description = "Whether to enable the Windows Azure Linux Agent."; default = false;
description = "Whether to enable the Windows Azure Linux Agent.";
};
verboseLogging = mkOption {
default = false;
description = "Whether to enable verbose logging.";
};
}; };
###### implementation ###### implementation
@ -88,7 +97,7 @@ in
Provisioning.DeleteRootPassword=n Provisioning.DeleteRootPassword=n
# Generate fresh host key pair. # Generate fresh host key pair.
Provisioning.RegenerateSshHostKeyPair=y Provisioning.RegenerateSshHostKeyPair=n
# Supported values are "rsa", "dsa" and "ecdsa". # Supported values are "rsa", "dsa" and "ecdsa".
Provisioning.SshHostKeyPairType=ed25519 Provisioning.SshHostKeyPairType=ed25519
@ -121,7 +130,7 @@ in
Logs.Console=y Logs.Console=y
# Enable verbose logging (y|n) # Enable verbose logging (y|n)
Logs.Verbose=n Logs.Verbose=${if cfg.verboseLogging then "y" else "n"}
# Root device timeout in seconds. # Root device timeout in seconds.
OS.RootDeviceScsiTimeout=300 OS.RootDeviceScsiTimeout=300
@ -146,16 +155,30 @@ in
systemd.targets.provisioned = { systemd.targets.provisioned = {
description = "Services Requiring Azure VM provisioning to have finished"; description = "Services Requiring Azure VM provisioning to have finished";
wantedBy = [ "sshd.service" ];
before = [ "sshd.service" ];
}; };
systemd.services.consume-hypervisor-entropy =
{ description = "Consume entropy in ACPI table provided by Hyper-V";
wantedBy = [ "sshd.service" "waagent.service" ];
before = [ "sshd.service" "waagent.service" ];
after = [ "local-fs.target" ];
path = [ pkgs.coreutils ];
script =
''
echo "Fetching entropy..."
cat /sys/firmware/acpi/tables/OEM0 > /dev/random
'';
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
serviceConfig.StandardError = "journal+console";
serviceConfig.StandardOutput = "journal+console";
};
systemd.services.waagent = { systemd.services.waagent = {
wantedBy = [ "sshd.service" ]; wantedBy = [ "multi-user.target" ];
before = [ "sshd.service" ]; after = [ "ip-up.target" "sshd.service" ];
after = [ "ip-up.target" ];
wants = [ "ip-up.target" ];
path = [ pkgs.e2fsprogs ]; path = [ pkgs.e2fsprogs ];
description = "Windows Azure Agent Service"; description = "Windows Azure Agent Service";

View File

@ -2,7 +2,7 @@
with lib; with lib;
let let
diskSize = "4096"; diskSize = "30720";
in in
{ {
system.build.azureImage = system.build.azureImage =
@ -23,7 +23,7 @@ in
postVM = postVM =
'' ''
mkdir -p $out mkdir -p $out
${pkgs.vmTools.qemu-220}/bin/qemu-img convert -f raw -O vpc -o subformat=fixed $diskImage $out/disk.vhd ${pkgs.vmTools.qemu-220}/bin/qemu-img convert -f raw -O vpc $diskImage $out/disk.vhd
rm $diskImage rm $diskImage
''; '';
diskImageBase = "nixos-image-${config.system.nixosLabel}-${pkgs.stdenv.system}.raw"; diskImageBase = "nixos-image-${config.system.nixosLabel}-${pkgs.stdenv.system}.raw";

View File

@ -22,7 +22,9 @@ in {
config = { config = {
system.build.virtualBoxImage = import ../../lib/make-disk-image.nix { system.build.virtualBoxOVA = import ../../lib/make-disk-image.nix {
name = "nixos-ova-${config.system.nixosLabel}-${pkgs.stdenv.system}";
inherit pkgs lib config; inherit pkgs lib config;
partitioned = true; partitioned = true;
diskSize = cfg.baseImageSize; diskSize = cfg.baseImageSize;
@ -37,37 +39,36 @@ in {
postVM = postVM =
'' ''
echo "creating VirtualBox disk image..." echo "creating VirtualBox disk image..."
${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi $diskImage $out/disk.vdi ${pkgs.vmTools.qemu}/bin/qemu-img convert -f raw -O vdi $diskImage disk.vdi
rm $diskImage rm $diskImage
echo "creating VirtualBox VM..."
export HOME=$PWD
export PATH=${pkgs.linuxPackages.virtualbox}/bin:$PATH
vmName="NixOS ${config.system.nixosLabel} (${pkgs.stdenv.system})"
VBoxManage createvm --name "$vmName" --register \
--ostype ${if pkgs.stdenv.system == "x86_64-linux" then "Linux26_64" else "Linux26"}
VBoxManage modifyvm "$vmName" \
--memory 1536 --acpi on --vram 32 \
${optionalString (pkgs.stdenv.system == "i686-linux") "--pae on"} \
--nictype1 virtio --nic1 nat \
--audiocontroller ac97 --audio alsa \
--rtcuseutc on \
--usb on --mouse usbtablet
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 disk.vdi
echo "exporting VirtualBox VM..."
mkdir -p $out
fn="$out/nixos-${config.system.nixosLabel}-${pkgs.stdenv.system}.ova"
VBoxManage export "$vmName" --output "$fn"
mkdir -p $out/nix-support
echo "file ova $fn" >> $out/nix-support/hydra-build-products
''; '';
}; };
system.build.virtualBoxOVA = pkgs.runCommand "virtualbox-ova"
{ buildInputs = [ pkgs.linuxPackages.virtualbox ];
vmName = "NixOS ${config.system.nixosLabel} (${pkgs.stdenv.system})";
fileName = "nixos-image-${config.system.nixosLabel}-${pkgs.stdenv.system}.ova";
}
''
echo "creating VirtualBox VM..."
export HOME=$PWD
VBoxManage createvm --name "$vmName" --register \
--ostype ${if pkgs.stdenv.system == "x86_64-linux" then "Linux26_64" else "Linux26"}
VBoxManage modifyvm "$vmName" \
--memory 1536 --acpi on --vram 32 \
${optionalString (pkgs.stdenv.system == "i686-linux") "--pae on"} \
--nictype1 virtio --nic1 nat \
--audiocontroller ac97 --audio alsa \
--rtcuseutc on \
--usb on --mouse usbtablet
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"; fileSystems."/".device = "/dev/disk/by-label/nixos";
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";

View File

@ -44,11 +44,11 @@ in rec {
(all nixos.manual) (all nixos.manual)
(all nixos.iso_minimal) (all nixos.iso_minimal)
(all nixos.iso_graphical) nixos.iso_graphical.x86_64-linux
(all nixos.ova) nixos.ova.x86_64-linux
#(all nixos.tests.containers) #(all nixos.tests.containers)
(all nixos.tests.chromium.stable) #(all nixos.tests.chromium.stable)
(all nixos.tests.firefox) (all nixos.tests.firefox)
(all nixos.tests.firewall) (all nixos.tests.firewall)
nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux nixos.tests.gnome3.x86_64-linux # FIXME: i686-linux

View File

@ -43,34 +43,14 @@ let
makeIso = makeIso =
{ module, type, description ? type, maintainers ? ["eelco"], system }: { module, type, maintainers ? ["eelco"], system }:
with import nixpkgs { inherit system; }; with import nixpkgs { inherit system; };
let hydraJob ((import lib/eval-config.nix {
inherit system;
config = (import lib/eval-config.nix { modules = [ module versionModule { isoImage.isoBaseName = "nixos-${type}"; } ];
inherit system; }).config.system.build.isoImage);
modules = [ module versionModule { isoImage.isoBaseName = "nixos-${type}"; } ];
}).config;
iso = config.system.build.isoImage;
in
# Declare the ISO as a build product so that it shows up in Hydra.
hydraJob (runCommand "nixos-iso-${config.system.nixosVersion}"
{ meta = {
description = "NixOS installation CD (${description}) - ISO image for ${system}";
maintainers = map (x: lib.maintainers.${x}) maintainers;
};
inherit iso;
passthru = { inherit config; };
preferLocalBuild = true;
}
''
mkdir -p $out/nix-support
echo "file iso" $iso/iso/*.iso* >> $out/nix-support/hydra-build-products
''); # */
makeSystemTarball = makeSystemTarball =
@ -130,7 +110,7 @@ in rec {
inherit system; inherit system;
}); });
iso_graphical = forAllSystems (system: makeIso { iso_graphical = genAttrs [ "x86_64-linux" ] (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-graphical-kde.nix; module = ./modules/installer/cd-dvd/installation-cd-graphical-kde.nix;
type = "graphical"; type = "graphical";
inherit system; inherit system;
@ -138,7 +118,7 @@ in rec {
# A variant with a more recent (but possibly less stable) kernel # A variant with a more recent (but possibly less stable) kernel
# that might support more hardware. # that might support more hardware.
iso_minimal_new_kernel = forAllSystems (system: makeIso { iso_minimal_new_kernel = genAttrs [ "x86_64-linux" ] (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix; module = ./modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix;
type = "minimal-new-kernel"; type = "minimal-new-kernel";
inherit system; inherit system;
@ -146,35 +126,17 @@ in rec {
# A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF). # A bootable VirtualBox virtual appliance as an OVA file (i.e. packaged OVF).
ova = forAllSystems (system: ova = genAttrs [ "x86_64-linux" ] (system:
with import nixpkgs { inherit system; }; with import nixpkgs { inherit system; };
let hydraJob ((import lib/eval-config.nix {
inherit system;
config = (import lib/eval-config.nix { modules =
inherit system; [ versionModule
modules = ./modules/installer/virtualbox-demo.nix
[ versionModule ];
./modules/installer/virtualbox-demo.nix }).config.system.build.virtualBoxOVA)
];
}).config;
in
# Declare the OVA as a build product so that it shows up in Hydra.
hydraJob (runCommand "nixos-ova-${config.system.nixosVersion}-${system}"
{ meta = {
description = "NixOS VirtualBox appliance (${system})";
maintainers = maintainers.eelco;
};
ova = config.system.build.virtualBoxOVA;
preferLocalBuild = true;
}
''
mkdir -p $out/nix-support
fn=$(echo $ova/*.ova)
echo "file ova $fn" >> $out/nix-support/hydra-build-products
'') # */
); );
@ -240,6 +202,7 @@ in rec {
tests.containers = callTest tests/containers.nix {}; tests.containers = callTest tests/containers.nix {};
tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; }); tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; });
tests.dockerRegistry = hydraJob (import tests/docker-registry.nix { system = "x86_64-linux"; }); tests.dockerRegistry = hydraJob (import tests/docker-registry.nix { system = "x86_64-linux"; });
tests.dnscrypt-proxy = callTest tests/dnscrypt-proxy.nix { system = "x86_64-linux"; };
tests.etcd = hydraJob (import tests/etcd.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-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;

View File

@ -1,4 +1,11 @@
{ system ? builtins.currentSystem }: { system ? builtins.currentSystem
, pkgs ? import ../.. { inherit system; }
, channelMap ? {
stable = pkgs.chromium;
beta = pkgs.chromiumBeta;
dev = pkgs.chromiumDev;
}
}:
with import ../lib/testing.nix { inherit system; }; with import ../lib/testing.nix { inherit system; };
with pkgs.lib; with pkgs.lib;
@ -160,8 +167,4 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
$machine->shutdown; $machine->shutdown;
''; '';
}) { }) channelMap
stable = pkgs.chromium;
beta = pkgs.chromiumBeta;
dev = pkgs.chromiumDev;
}

View File

@ -0,0 +1,33 @@
import ./make-test.nix ({ pkgs, ... }: {
name = "dnscrypt-proxy";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ joachifm ];
};
nodes = {
# A client running the recommended setup: DNSCrypt proxy as a forwarder
# for a caching DNS client.
client =
{ config, pkgs, ... }:
let localProxyPort = 43; in
{
security.apparmor.enable = true;
services.dnscrypt-proxy.enable = true;
services.dnscrypt-proxy.localPort = localProxyPort;
services.dnsmasq.enable = true;
services.dnsmasq.servers = [ "127.0.0.1#${toString localProxyPort}" ];
};
};
testScript = ''
$client->start;
$client->waitForUnit("sockets.target");
$client->waitForUnit("dnsmasq");
# The daemon is socket activated; sending a single ping should activate it.
$client->execute("${pkgs.iputils}/bin/ping -c1 example.com");
$client->succeed("systemctl is-active dnscrypt-proxy");
'';
})

View File

@ -20,7 +20,7 @@ import ./make-test.nix ({ pkgs, ...} : {
testScript = '' testScript = ''
startAll; startAll;
$docker->waitForUnit("docker.service"); $docker->waitForUnit("sockets.target");
$docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg"); $docker->succeed("tar cv --files-from /dev/null | docker import - scratchimg");
$docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"); $docker->succeed("docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10");
$docker->succeed("docker ps | grep sleeping"); $docker->succeed("docker ps | grep sleeping");

View File

@ -35,9 +35,9 @@ import ./make-test.nix ( { pkgs, ... } : {
# Local connections should still work. # Local connections should still work.
$walled->succeed("curl -v http://localhost/ >&2"); $walled->succeed("curl -v http://localhost/ >&2");
# Connections to the firewalled machine should fail. # Connections to the firewalled machine should fail, but ping should succeed.
$attacker->fail("curl --fail --connect-timeout 2 http://walled/ >&2"); $attacker->fail("curl --fail --connect-timeout 2 http://walled/ >&2");
$attacker->fail("ping -c 1 walled >&2"); $attacker->succeed("ping -c 1 walled >&2");
# Outgoing connections/pings should still work. # Outgoing connections/pings should still work.
$walled->succeed("curl -v http://attacker/ >&2"); $walled->succeed("curl -v http://attacker/ >&2");

View File

@ -23,6 +23,8 @@ import ./make-test.nix ({ pkgs, ...} : {
{ wantedBy = [ "multi-user.target" ]; { wantedBy = [ "multi-user.target" ];
where = "/tmp2"; where = "/tmp2";
}; };
users.users.sybil = { isNormalUser = true; group = "wheel"; };
security.sudo = { enable = true; wheelNeedsPassword = false; };
}; };
testScript = testScript =
@ -110,5 +112,10 @@ import ./make-test.nix ({ pkgs, ...} : {
subtest "nix-db", sub { subtest "nix-db", sub {
$machine->succeed("nix-store -qR /run/current-system | grep nixos-"); $machine->succeed("nix-store -qR /run/current-system | grep nixos-");
}; };
# Test sudo
subtest "sudo", sub {
$machine->succeed("su - sybil -c 'sudo true'");
};
''; '';
}) })

View File

@ -7,7 +7,7 @@ import ./make-test.nix {
{ {
services.riak.enable = true; services.riak.enable = true;
services.riak.package = pkgs.riak2; services.riak.package = pkgs.riak;
}; };
}; };

View File

@ -0,0 +1,55 @@
{ pkgs, stdenv, lib, fetchurl, intltool, pkgconfig, gstreamer, gst_plugins_base
, gst_plugins_good, gst_plugins_bad, gst_plugins_ugly, gst_ffmpeg, glib
, mono, mono-addins, dbus-sharp-1_0, dbus-sharp-glib-1_0, notify-sharp, gtk-sharp-2_0
, boo, gdata-sharp, taglib-sharp, sqlite, gnome-sharp, gconf, gtk-sharp-beans, gio-sharp
, libmtp, libgpod, mono-zeroconf }:
stdenv.mkDerivation rec {
name = "banshee-${version}";
version = "2.6.2";
src = fetchurl {
url = "http://ftp.gnome.org/pub/GNOME/sources/banshee/2.6/banshee-${version}.tar.xz";
sha256 = "1y30p8wxx5li39i5gpq2wib0ympy8llz0gyi6ri9bp730ndhhz7p";
};
dontStrip = true;
nativeBuildInputs = [ pkgconfig intltool ];
buildInputs = [
gtk-sharp-2_0.gtk gstreamer gst_plugins_base gst_plugins_good
gst_plugins_bad gst_plugins_ugly gst_ffmpeg
mono dbus-sharp-1_0 dbus-sharp-glib-1_0 mono-addins notify-sharp
gtk-sharp-2_0 boo gdata-sharp taglib-sharp sqlite gnome-sharp gconf gtk-sharp-beans
gio-sharp libmtp libgpod mono-zeroconf
];
makeFlags = [ "PREFIX=$(out)" ];
postPatch = ''
patchShebangs data/desktop-files/update-desktop-file.sh
patchShebangs build/private-icon-theme-installer
sed -i "s,DOCDIR=.*,DOCDIR=$out/lib/monodoc," configure
'';
postInstall = let
ldLibraryPath = lib.makeLibraryPath [ gtk-sharp-2_0.gtk gtk-sharp-2_0 sqlite gconf glib gstreamer ];
monoGACPrefix = lib.concatStringsSep ":" [
mono dbus-sharp-1_0 dbus-sharp-glib-1_0 mono-addins notify-sharp gtk-sharp-2_0
boo gdata-sharp taglib-sharp sqlite gnome-sharp gconf gtk-sharp-beans
gio-sharp libmtp libgpod mono-zeroconf
];
in ''
sed -e '2a export MONO_GAC_PREFIX=${monoGACPrefix}' \
-e 's|LD_LIBRARY_PATH=|LD_LIBRARY_PATH=${ldLibraryPath}:|' \
-e "s|GST_PLUGIN_PATH=|GST_PLUGIN_PATH=$GST_PLUGIN_SYSTEM_PATH:|" \
-e 's| mono | ${mono}/bin/mono |' \
-i $out/bin/banshee
'';
meta = with lib; {
description = "A music player written in C# using GNOME technologies";
platforms = platforms.linux;
maintainers = [ maintainers.zohl ];
};
}

View File

@ -3,12 +3,12 @@
}: }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
version = "0.9.8.1"; version = "0.9.9";
name = "drumgizmo-${version}"; name = "drumgizmo-${version}";
src = fetchurl { src = fetchurl {
url = "http://www.drumgizmo.org/releases/${name}/${name}.tar.gz"; url = "http://www.drumgizmo.org/releases/${name}/${name}.tar.gz";
sha256 = "1plfjhwhaz1mr3kgf5imcp3kjflk6ni9sq39gmxjxzya6gn2r6gg"; sha256 = "03dnh2p4s6n107n0r86h9j1jwy85a8qwjkh0288k60qpdqy1c7vp";
}; };
configureFlags = [ "--enable-lv2" ]; configureFlags = [ "--enable-lv2" ];
@ -21,7 +21,7 @@ stdenv.mkDerivation rec {
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "An LV2 sample based drum plugin"; description = "An LV2 sample based drum plugin";
homepage = http://www.drumgizmo.org; homepage = http://www.drumgizmo.org;
license = licenses.gpl3; license = licenses.lgpl3;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = [ maintainers.goibhniu maintainers.nico202 ]; maintainers = [ maintainers.goibhniu maintainers.nico202 ];
}; };

View File

@ -20,7 +20,6 @@ in stdenv.mkDerivation rec {
license = licenses.gpl2Plus; license = licenses.gpl2Plus;
platforms = platforms.linux; platforms = platforms.linux;
hydraPlatforms = []; hydraPlatforms = [];
maintainers = with maintainers; [ iyzsong ];
}; };
src = fetchurl { src = fetchurl {

View File

@ -37,7 +37,8 @@ let
inherit src; inherit src;
buildInputs = [ makeWrapper llvm emscripten openssl libsndfile pkgconfig libmicrohttpd vim ]; nativeBuildInputs = [ makeWrapper pkgconfig vim ];
buildInputs = [ llvm emscripten openssl libsndfile libmicrohttpd ];
passthru = { passthru = {
@ -53,6 +54,20 @@ let
# correct system. # correct system.
unset system unset system
sed -e "232s/LLVM_STATIC_LIBS/LLVMLIBS/" -i compiler/Makefile.unix sed -e "232s/LLVM_STATIC_LIBS/LLVMLIBS/" -i compiler/Makefile.unix
# The makefile sets LLVM_<version> depending on the current llvm
# version, but the detection code is quite brittle.
#
# Failing to properly detect the llvm version means that the macro
# LLVM_VERSION ends up being the raw output of `llvm-config --version`, while
# the code assumes that it's set to a symbol like `LLVM_35`. Two problems result:
# * <command-line>:0:1: error: macro names must be identifiers.; and
# * a bunch of undefined reference errors due to conditional definitions relying on
# LLVM_XY being defined.
#
# For now, fix this by 1) pinning the llvm version; 2) manually setting LLVM_VERSION
# to something the makefile will recognize.
sed '52iLLVM_VERSION=3.7.0' -i compiler/Makefile.unix
''; '';
# Remove most faust2appl scripts since they won't run properly # Remove most faust2appl scripts since they won't run properly

View File

@ -1,5 +1,5 @@
{ stdenv, fetchurl, alsaLib, glib, libjack2, libsndfile, pkgconfig { stdenv, fetchurl, alsaLib, glib, libjack2, libsndfile, pkgconfig
, libpulseaudio }: , libpulseaudio, CoreServices, CoreAudio, AudioUnit }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "fluidsynth-${version}"; name = "fluidsynth-${version}";
@ -18,10 +18,11 @@ stdenv.mkDerivation rec {
''; '';
NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isDarwin NIX_LDFLAGS = stdenv.lib.optionalString stdenv.isDarwin
"-framework CoreAudio"; "-framework CoreAudio -framework CoreServices";
buildInputs = [ glib libsndfile pkgconfig ] buildInputs = [ glib libsndfile pkgconfig ]
++ stdenv.lib.optionals (!stdenv.isDarwin) [ alsaLib libpulseaudio libjack2 ]; ++ stdenv.lib.optionals (!stdenv.isDarwin) [ alsaLib libpulseaudio libjack2 ]
++ stdenv.lib.optionals stdenv.isDarwin [ CoreServices CoreAudio AudioUnit ];
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "Real-time software synthesizer based on the SoundFont 2 specifications"; description = "Real-time software synthesizer based on the SoundFont 2 specifications";

View File

@ -1,23 +1,23 @@
{ stdenv, fetchFromGitHub, pkgconfig, python2, cairo, libjpeg, ntk, libjack2, libsndfile, { stdenv, fetchFromGitHub, pkgconfig, python2, cairo, libjpeg, ntk, libjack2
ladspaH, liblrdf, liblo, libsigcxx , libsndfile, ladspaH, liblrdf, liblo, libsigcxx
}: }:
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "non-${version}"; name = "non-${version}";
version = "2016-02-07"; version = "2016-03-06";
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "original-male"; owner = "original-male";
repo = "non"; repo = "non";
rev = "1ef382fbbea598fdb56b25244a703c64ecaf8446"; rev = "3946d392216ee999b560d8b7cdee7c4347110e29";
sha256 = "1mi3nm0nrrqlk36920irvqf5080lbnj1qc8vnxspgwkjjqgdc22g"; sha256 = "02vnq2mfimgdrmv3lmz80yif4h9a1lympv0wqc5dr2l0f8amj2fp";
}; };
buildInputs = [ pkgconfig python2 cairo libjpeg ntk libjack2 libsndfile buildInputs = [ pkgconfig python2 cairo libjpeg ntk libjack2 libsndfile
ladspaH liblrdf liblo libsigcxx ladspaH liblrdf liblo libsigcxx
]; ];
configurePhase = ''python waf configure --prefix=$out''; configurePhase = "python waf configure --prefix=$out";
buildPhase = ''python waf build''; buildPhase = "python waf build";
installPhase = ''python waf install''; installPhase = "python waf install";
meta = { meta = {
description = "Lightweight and lightning fast modular Digital Audio Workstation"; description = "Lightweight and lightning fast modular Digital Audio Workstation";

View File

@ -19,6 +19,11 @@ pythonPackages.buildPythonApplication rec {
substituteInPlace setup.py --replace "/usr/share" "$out/share" substituteInPlace setup.py --replace "/usr/share" "$out/share"
''; '';
postInstall = ''
mkdir -p $out/share/applications
cp -v data/pithos.desktop $out/share/applications
'';
buildInputs = [ wrapGAppsHook ]; buildInputs = [ wrapGAppsHook ];
propagatedBuildInputs = propagatedBuildInputs =

View File

@ -6,6 +6,9 @@ stdenv.mkDerivation rec {
url = "https://rubyripper.googlecode.com/files/rubyripper-${version}.tar.bz2"; url = "https://rubyripper.googlecode.com/files/rubyripper-${version}.tar.bz2";
sha256 = "1fwyk3y0f45l2vi3a481qd7drsy82ccqdb8g2flakv58m45q0yl1"; sha256 = "1fwyk3y0f45l2vi3a481qd7drsy82ccqdb8g2flakv58m45q0yl1";
}; };
preConfigure = "patchShebangs .";
configureFlags = [ "--enable-cli" ]; configureFlags = [ "--enable-cli" ];
buildInputs = [ ruby cdparanoia makeWrapper ]; buildInputs = [ ruby cdparanoia makeWrapper ];
postInstall = '' postInstall = ''

View File

@ -2,20 +2,21 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "seq24-${version}"; name = "seq24-${version}";
version = "0.9.2"; version = "0.9.3";
src = fetchurl { src = fetchurl {
url = "http://launchpad.net/seq24/trunk/${version}/+download/${name}.tar.gz"; url = "http://launchpad.net/seq24/trunk/${version}/+download/${name}.tar.gz";
sha256 = "07n80zj95i80vjmsflnlbqx5vv90qmp5f6a0zap8d30849l4y258"; sha256 = "1qpyb7355s21sgy6gibkybxpzx4ikha57a8w644lca6qy9mhcwi3";
}; };
buildInputs = [ alsaLib gtkmm libjack2 pkgconfig ]; buildInputs = [ alsaLib gtkmm libjack2 ];
nativeBuildInputs = [ pkgconfig ];
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "minimal loop based midi sequencer"; description = "minimal loop based midi sequencer";
homepage = "http://www.filter24.org/seq24"; homepage = "http://www.filter24.org/seq24";
license = licenses.gpl2; license = licenses.gpl2;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = [ maintainers.goibhniu ]; maintainers = with maintainers; [ goibhniu nckx ];
}; };
} }

View File

@ -5,7 +5,7 @@
assert stdenv.system == "x86_64-linux"; assert stdenv.system == "x86_64-linux";
let let
version = "1.0.23.93.gd6cfae15-30"; version = "1.0.25.127.g58007b4c-22";
deps = [ deps = [
alsaLib alsaLib
@ -50,7 +50,7 @@ stdenv.mkDerivation {
src = src =
fetchurl { fetchurl {
url = "http://repository-origin.spotify.com/pool/non-free/s/spotify-client/spotify-client_${version}_amd64.deb"; url = "http://repository-origin.spotify.com/pool/non-free/s/spotify-client/spotify-client_${version}_amd64.deb";
sha256 = "0n6vz51jv6s20dp4zlqkk52bpmpyfm1qn5bfm4lfq09x1g6ir5lr"; sha256 = "1fxps0ls0g4idw10la3qrpmp2jn85lkm3xj4nam4ycx0jj8g1v2p";
}; };
buildInputs = [ dpkg makeWrapper ]; buildInputs = [ dpkg makeWrapper ];

View File

@ -12,7 +12,6 @@ in stdenv.mkDerivation rec {
homepage = "http://vmpk.sourceforge.net/"; homepage = "http://vmpk.sourceforge.net/";
license = licenses.gpl3Plus; license = licenses.gpl3Plus;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = with maintainers; [ iyzsong ];
}; };
src = fetchurl { src = fetchurl {

View File

@ -8,7 +8,6 @@ stdenv.mkDerivation rec {
homepage = "http://xmp.sourceforge.net/"; homepage = "http://xmp.sourceforge.net/";
license = licenses.gpl2Plus; license = licenses.gpl2Plus;
platforms = platforms.linux; platforms = platforms.linux;
maintainers = with maintainers; [ iyzsong ];
}; };
src = fetchurl { src = fetchurl {

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