Merge remote-tracking branch 'origin/master' into stdenv-updates.

Conflicts:
	pkgs/development/interpreters/perl/5.16/default.nix
	pkgs/tools/networking/curl/default.nix
	pkgs/top-level/all-packages.nix
	pkgs/top-level/release-python.nix
	pkgs/top-level/release-small.nix
	pkgs/top-level/release.nix
This commit is contained in:
Peter Simons 2013-12-04 18:33:45 +01:00
commit c32bf83301
765 changed files with 14556 additions and 11365 deletions

View File

@ -1 +1 @@
13.10 14.02

View File

@ -118,6 +118,56 @@ interpretation:</para>
package).</para></listitem> package).</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>platforms</varname></term>
<listitem><para>The list of Nix platform types on which the
package is supported. If this attribute is set, the package will
refuse to build, and wont show up in <literal>nix-env
-qa</literal> output, on any platform not listed
here. An example is:
<programlisting>
meta.platforms = [ "x86_64-linux" "i686-linux" "x86_64-darwin" ];
</programlisting>
The set <varname>lib.platforms</varname> defines various common
lists of platforms types, so its more typical to write:
<programlisting>
meta.platforms = stdenv.lib.platforms.linux ++ stdenv.lib.platforms.darwin;
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>hydraPlatforms</varname></term>
<listitem><para>The list of Nix platform types for which the Hydra
instance at <literal>hydra.nixos.org</literal> should build the
package. (Hydra is the Nix-based continuous build system.) It
defaults to the value of <varname>meta.platforms</varname>. Thus,
the only reason to set <varname>meta.hydraPlatforms</varname> is
if you want <literal>hydra.nixos.org</literal> to build the
package on a subset of <varname>meta.platforms</varname>, or not
at all, e.g.
<programlisting>
meta.platforms = stdenv.lib.platforms.linux;
meta.hydraPlatforms = [];
</programlisting>
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>broken</varname></term>
<listitem><para>If set to <literal>true</literal>, the package is
marked as “broken”, meaning that it wont show up in
<literal>nix-env -qa</literal>, and cannot be built or installed.
Sush packages should be removed from Nixpkgs eventually unless
they are fixed.</para></listitem>
</varlistentry>
</variablelist> </variablelist>

View File

@ -1,7 +1,7 @@
# Operations on attribute sets. # Operations on attribute sets.
with { with {
inherit (builtins) head tail isString; inherit (builtins) head tail;
inherit (import ./trivial.nix) or; inherit (import ./trivial.nix) or;
inherit (import ./default.nix) fold; inherit (import ./default.nix) fold;
inherit (import ./strings.nix) concatStringsSep; inherit (import ./strings.nix) concatStringsSep;
@ -20,7 +20,7 @@ rec {
let attr = head attrPath; let attr = head attrPath;
in in
if attrPath == [] then e if attrPath == [] then e
else if builtins ? hasAttr && hasAttr attr e else if hasAttr attr e
then attrByPath (tail attrPath) default (getAttr attr e) then attrByPath (tail attrPath) default (getAttr attr e)
else default; else default;
@ -100,7 +100,7 @@ rec {
(AttrSet -> Bool) -> AttrSet -> AttrSet (AttrSet -> Bool) -> AttrSet -> AttrSet
Example: Example:
collect builtins.isList { a = { b = ["b"]; }; c = [1]; } collect isList { a = { b = ["b"]; }; c = [1]; }
=> [["b"] [1]] => [["b"] [1]]
collect (x: x ? outPath) collect (x: x ? outPath)
@ -110,7 +110,7 @@ rec {
collect = pred: attrs: collect = pred: attrs:
if pred attrs then if pred attrs then
[ attrs ] [ attrs ]
else if builtins.isAttrs attrs then else if isAttrs attrs then
concatMap (collect pred) (attrValues attrs) concatMap (collect pred) (attrValues attrs)
else else
[]; [];

View File

@ -21,8 +21,6 @@ let
in in
{ inherit trivial lists strings stringsWithDeps attrsets sources options { inherit trivial lists strings stringsWithDeps attrsets sources options
modules types meta debug maintainers licenses platforms systems; modules types meta debug maintainers licenses platforms systems;
# Pull in some builtins not included elsewhere.
inherit (builtins) pathExists readFile;
} }
# !!! don't include everything at top-level; perhaps only the most # !!! don't include everything at top-level; perhaps only the most
# commonly used functions. # commonly used functions.

View File

@ -1,14 +1,16 @@
# General list operations. # General list operations.
let
inherit (import ./trivial.nix) deepSeq; with import ./trivial.nix;
let
inc = builtins.add 1; inc = builtins.add 1;
dec = n: builtins.sub n 1; dec = n: builtins.sub n 1;
in rec { in rec {
inherit (builtins) head tail length isList add sub lessThan elemAt;
inherit (builtins) head tail length isList elemAt concatLists filter elem;
# Create a list consisting of a single element. `singleton x' is # Create a list consisting of a single element. `singleton x' is
@ -56,10 +58,6 @@ in rec {
in imap' 0; in imap' 0;
# Concatenate a list of lists.
concatLists = builtins.concatLists or (fold (x: y: x ++ y) []);
# Map and concatenate the result. # Map and concatenate the result.
concatMap = f: list: concatLists (map f list); concatMap = f: list: concatLists (map f list);
@ -73,24 +71,10 @@ in rec {
else [x]; else [x];
# Filter a list using a predicate; that is, return a list containing
# every element from `list' for which `pred' returns true.
filter =
builtins.filter or
(pred: list:
fold (x: y: if pred x then [x] ++ y else y) [] list);
# Remove elements equal to 'e' from a list. Useful for buildInputs. # Remove elements equal to 'e' from a list. Useful for buildInputs.
remove = e: filter (x: x != e); remove = e: filter (x: x != e);
# Return true if `list' has an element `x'.
elem =
builtins.elem or
(x: list: fold (a: bs: x == a || bs) false list);
# Find the sole element in the list matching the specified # Find the sole element in the list matching the specified
# predicate, returns `default' if no such element exists, or # predicate, returns `default' if no such element exists, or
# `multiple' if there are multiple matching elements. # `multiple' if there are multiple matching elements.
@ -136,14 +120,14 @@ in rec {
# If argument is a list, return it; else, wrap it in a singleton # If argument is a list, return it; else, wrap it in a singleton
# list. If you're using this, you should almost certainly # list. If you're using this, you should almost certainly
# reconsider if there isn't a more "well-typed" approach. # reconsider if there isn't a more "well-typed" approach.
toList = x: if builtins.isList x then x else [x]; toList = x: if isList x then x else [x];
# Return a list of integers from `first' up to and including `last'. # Return a list of integers from `first' up to and including `last'.
range = first: last: range = first: last:
if builtins.lessThan last first if lessThan last first
then [] then []
else [first] ++ range (builtins.add first 1) last; else [first] ++ range (add first 1) last;
# Partition the elements of a list in two lists, `right' and # Partition the elements of a list in two lists, `right' and
@ -160,7 +144,7 @@ in rec {
let let
len1 = length fst; len1 = length fst;
len2 = length snd; len2 = length snd;
len = if builtins.lessThan len1 len2 then len1 else len2; len = if lessThan len1 len2 then len1 else len2;
zipListsWith' = n: zipListsWith' = n:
if n != len then if n != len then
[ (f (elemAt fst n) (elemAt snd n)) ] [ (f (elemAt fst n) (elemAt snd n)) ]
@ -220,6 +204,7 @@ in rec {
in drop' (dec len); in drop' (dec len);
# Return the last element of a list.
last = list: last = list:
assert list != []; elemAt list (dec (length list)); assert list != []; elemAt list (dec (length list));
@ -237,5 +222,7 @@ in rec {
else []; else [];
in zipTwoLists' 0; in zipTwoLists' 0;
deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y; deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y;
} }

View File

@ -55,6 +55,7 @@
smironov = "Sergey Mironov <ierton@gmail.com>"; smironov = "Sergey Mironov <ierton@gmail.com>";
thammers = "Tobias Hammerschmidt <jawr@gmx.de>"; thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>"; the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
vcunat = "Vladimír Čunát <vcunat@gmail.com>"; vcunat = "Vladimír Čunát <vcunat@gmail.com>";
viric = "Lluís Batlle i Rossell <viric@viric.name>"; viric = "Lluís Batlle i Rossell <viric@viric.name>";
@ -63,4 +64,6 @@
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>"; winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>"; z77z = "Marco Maggesi <maggesi@math.unifi.it>";
zef = "Zef Hemel <zef@zef.me>"; zef = "Zef Hemel <zef@zef.me>";
zimbatm = "zimbatm <zimbatm@zimbatm.com>";
zoomulator = "Kim Simmons <zoomulator@gmail.com>";
} }

View File

@ -42,7 +42,7 @@ rec {
closeModules = modules: args: closeModules = modules: args:
let let
toClosureList = file: parentKey: imap (n: x: toClosureList = file: parentKey: imap (n: x:
if isAttrs x || builtins.isFunction x then if isAttrs x || isFunction x then
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args) unifyModuleSyntax file "${parentKey}:anon-${toString n}" (applyIfFunction x args)
else else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args)); unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
@ -74,7 +74,7 @@ rec {
config = removeAttrs m ["key" "_file" "require" "imports"]; config = removeAttrs m ["key" "_file" "require" "imports"];
}; };
applyIfFunction = f: arg: if builtins.isFunction f then f arg else f; applyIfFunction = f: arg: if isFunction f then f arg else f;
/* Merge a list of modules. This will recurse over the option /* Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set. declarations in all modules, combining them into a single set.
@ -260,7 +260,7 @@ rec {
options' = opt.options or options' = opt.options or
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute."); (throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
coerce = x: coerce = x:
if builtins.isFunction x then x if isFunction x then x
else { config, ... }: { options = x; }; else { config, ... }: { options = x; };
options = map coerce (flatten options'); options = map coerce (flatten options');
f = tp: f = tp:

View File

@ -34,12 +34,12 @@ rec {
mergeDefaultOption = loc: defs: mergeDefaultOption = loc: defs:
let list = getValues defs; in let list = getValues defs; in
if length list == 1 then head list if length list == 1 then head list
else if all builtins.isFunction list then x: mergeDefaultOption loc (map (f: f x) list) else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list)
else if all isList list then concatLists list else if all isList list then concatLists list
else if all isAttrs list then fold lib.mergeAttrs {} list else if all isAttrs list then fold lib.mergeAttrs {} list
else if all builtins.isBool list then fold lib.or false list else if all isBool list then fold lib.or false list
else if all builtins.isString list then lib.concatStrings list else if all isString list then lib.concatStrings list
else if all builtins.isInt list && all (x: x == head list) list then head list else if all isInt list && all (x: x == head list) list then head list
else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}."; else throw "Cannot merge definitions of `${showOption loc}' given in ${showFiles (getFiles defs)}.";
/* Obsolete, will remove soon. Specify an option type or apply /* Obsolete, will remove soon. Specify an option type or apply
@ -54,7 +54,7 @@ rec {
mergeListOption = mergeTypedOption "list" isList concatLists; mergeListOption = mergeTypedOption "list" isList concatLists;
mergeStringOption = mergeTypedOption "string" builtins.isString lib.concatStrings; mergeStringOption = mergeTypedOption "string" isString lib.concatStrings;
mergeOneOption = loc: defs: mergeOneOption = loc: defs:
if defs == [] then abort "This case should never happen." if defs == [] then abort "This case should never happen."

View File

@ -2,9 +2,9 @@ let lists = import ./lists.nix; in
rec { rec {
gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */ gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */
linux = ["i686-linux" "x86_64-linux" "powerpc-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"]; linux = ["i686-linux" "x86_64-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"];
darwin = ["x86_64-darwin"]; darwin = ["x86_64-darwin"];
freebsd = ["i686-freebsd" "x86_64-freebsd" "powerpc-freebsd"]; freebsd = ["i686-freebsd" "x86_64-freebsd"];
openbsd = ["i686-openbsd" "x86_64-openbsd"]; openbsd = ["i686-openbsd" "x86_64-openbsd"];
netbsd = ["i686-netbsd" "x86_64-netbsd"]; netbsd = ["i686-netbsd" "x86_64-netbsd"];
cygwin = ["i686-cygwin"]; cygwin = ["i686-cygwin"];

View File

@ -7,7 +7,8 @@ inherit (builtins) add sub lessThan length;
in in
rec { rec {
inherit (builtins) stringLength substring head tail;
inherit (builtins) stringLength substring head tail isString;
# Concatenate a list of strings. # Concatenate a list of strings.

View File

@ -35,4 +35,10 @@ rec {
else if builtins.isAttrs x else if builtins.isAttrs x
then deepSeqAttrs x y then deepSeqAttrs x y
else seq x y; else seq x y;
# Pull in some builtins not included elsewhere.
inherit (builtins)
pathExists readFile isBool isFunction
isInt add sub lessThan;
} }

View File

@ -48,19 +48,19 @@ rec {
bool = mkOptionType { bool = mkOptionType {
name = "boolean"; name = "boolean";
check = builtins.isBool; check = isBool;
merge = loc: fold (x: y: x.value || y) false; merge = loc: fold (x: y: x.value || y) false;
}; };
int = mkOptionType { int = mkOptionType {
name = "integer"; name = "integer";
check = builtins.isInt; check = isInt;
merge = mergeOneOption; merge = mergeOneOption;
}; };
str = mkOptionType { str = mkOptionType {
name = "string"; name = "string";
check = builtins.isString; check = isString;
merge = mergeOneOption; merge = mergeOneOption;
}; };
@ -68,7 +68,7 @@ rec {
# separator between the values). # separator between the values).
separatedString = sep: mkOptionType { separatedString = sep: mkOptionType {
name = "string"; name = "string";
check = builtins.isString; check = isString;
merge = loc: defs: concatStringsSep sep (getValues defs); merge = loc: defs: concatStringsSep sep (getValues defs);
}; };
@ -170,7 +170,7 @@ rec {
functionTo = elemType: mkOptionType { functionTo = elemType: mkOptionType {
name = "function that evaluates to a(n) ${elemType.name}"; name = "function that evaluates to a(n) ${elemType.name}";
check = builtins.isFunction; check = isFunction;
merge = loc: defs: merge = loc: defs:
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs); fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
getSubOptions = elemType.getSubOptions; getSubOptions = elemType.getSubOptions;
@ -183,10 +183,10 @@ rec {
in in
mkOptionType rec { mkOptionType rec {
name = "submodule"; name = "submodule";
check = x: isAttrs x || builtins.isFunction x; check = x: isAttrs x || isFunction x;
merge = loc: defs: merge = loc: defs:
let let
coerce = def: if builtins.isFunction def then def else { config = def; }; coerce = def: if isFunction def then def else { config = def; };
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs; modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config; in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
getSubOptions = prefix: (evalModules getSubOptions = prefix: (evalModules

View File

@ -1,6 +1,4 @@
{ pkgs, options { pkgs, options, version, revision }:
, revision ? "master"
}:
with pkgs.lib; with pkgs.lib;
@ -60,6 +58,7 @@ in rec {
buildCommand = '' buildCommand = ''
ln -s $sources/*.xml . # */ ln -s $sources/*.xml . # */
ln -s ${optionsDocBook} options-db.xml ln -s ${optionsDocBook} options-db.xml
echo "${version}" > version
# Check the validity of the manual sources. # Check the validity of the manual sources.
xmllint --noout --nonet --xinclude --noxincludenode \ xmllint --noout --nonet --xinclude --noxincludenode \

View File

@ -652,6 +652,37 @@ $ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>systemd.units.<replaceable>unit-name</replaceable>.unit</varname></term>
<listitem>
<para>This builds the unit with the specified name. Note that
since unit names contain dots
(e.g. <literal>httpd.service</literal>), you need to put them
between quotes, like this:
<screen>
$ nix-build -A 'config.systemd.units."httpd.service".unit'
</screen>
You can also test individual units, without rebuilding the whole
system, by putting them in
<filename>/run/systemd/system</filename>:
<screen>
$ cp $(nix-build -A 'config.systemd.units."httpd.service".unit')/httpd.service \
/run/systemd/system/tmp-httpd.service
$ systemctl daemon-reload
$ systemctl start tmp-httpd.service
</screen>
Note that the unit must not have the same name as any unit in
<filename>/etc/systemd/system</filename> since those take
precedence over <filename>/run/systemd/system</filename>.
Thats why the unit is installed as
<filename>tmp-httpd.service</filename> here.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>

View File

@ -369,9 +369,23 @@ $ nixos-rebuild build-vm
$ ./result/bin/run-*-vm $ ./result/bin/run-*-vm
</screen> </screen>
The VM does not have use any data from your host system, so your The VM does not have any data from your host system, so your existing
existing user accounts and home directories will not be user accounts and home directories will not be available. You can
available.</para> forward ports on the host to the guest. For instance, the following
will forward host port 2222 to guest port 22 (SSH):
<screen>
$ QEMU_NET_OPTS="hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
</screen>
allowing you to log in via SSH (assuming you have set the appropriate
passwords or SSH authorized keys):
<screen>
$ ssh -p 2222 localhost
</screen>
</para>
</section> </section>

View File

@ -5,6 +5,7 @@
<info> <info>
<title>NixOS Manual</title> <title>NixOS Manual</title>
<subtitle>Version <xi:include href="version" parse="text" /></subtitle>
<author> <author>
<personname> <personname>

View File

@ -68,8 +68,8 @@ rec {
# the first interface (i.e. the first network in its # the first interface (i.e. the first network in its
# virtualisation.vlans option). # virtualisation.vlans option).
networking.extraHosts = flip concatMapStrings machines networking.extraHosts = flip concatMapStrings machines
(m: let config = (getAttr m nodes).config; in (m': let config = (getAttr m' nodes).config; in
optionalString (config.networking.primaryIPAddress != "") optionalString (m.first != m' && config.networking.primaryIPAddress != "")
("${config.networking.primaryIPAddress} " + ("${config.networking.primaryIPAddress} " +
"${config.networking.hostName}\n")); "${config.networking.hostName}\n"));

View File

@ -8,6 +8,7 @@
, extraArgs ? {} , extraArgs ? {}
, modules , modules
, check ? true , check ? true
, prefix ? []
}: }:
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
@ -17,6 +18,7 @@ rec {
# Merge the option definitions in all modules, forming the full # Merge the option definitions in all modules, forming the full
# system configuration. # system configuration.
inherit (pkgs.lib.evalModules { inherit (pkgs.lib.evalModules {
inherit prefix;
modules = modules ++ baseModules; modules = modules ++ baseModules;
args = extraArgs; args = extraArgs;
check = check && options.environment.checkConfigurationOptions.value; check = check && options.environment.checkConfigurationOptions.value;
@ -48,7 +50,7 @@ rec {
let let
system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_; system = if nixpkgsOptions.system != "" then nixpkgsOptions.system else system_;
nixpkgsOptions = (import ./eval-config.nix { nixpkgsOptions = (import ./eval-config.nix {
inherit system extraArgs modules; inherit system extraArgs modules prefix;
# For efficiency, leave out most NixOS modules; they don't # For efficiency, leave out most NixOS modules; they don't
# define nixpkgs.config, so it's pointless to evaluate them. # define nixpkgs.config, so it's pointless to evaluate them.
baseModules = [ ../modules/misc/nixpkgs.nix ]; baseModules = [ ../modules/misc/nixpkgs.nix ];

View File

@ -16,7 +16,7 @@ parser.add_argument('--hvm', dest='hvm', action='store_true', help='Create HVM i
parser.add_argument('--key', dest='key_name', action='store_true', help='Keypair used for HVM instance creation', default="rob") parser.add_argument('--key', dest='key_name', action='store_true', help='Keypair used for HVM instance creation', default="rob")
args = parser.parse_args() args = parser.parse_args()
instance_type = "cc1.4xlarge" if args.hvm else "m1.small" instance_type = "m3.xlarge" if args.hvm else "m1.small"
ebs_size = 8 if args.hvm else 20 ebs_size = 8 if args.hvm else 20
@ -67,12 +67,13 @@ m.run_command("mkdir -p /mnt/etc/nixos")
m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable") m.run_command("nix-channel --add http://nixos.org/channels/nixos-unstable")
m.run_command("nix-channel --update") m.run_command("nix-channel --update")
m.run_command("nixos-rebuild switch") m.run_command("nixos-rebuild switch")
version = m.run_command("nixos-version", capture_stdout=True).replace('"', '').rstrip() version = m.run_command("nixos-version", capture_stdout=True).split(' ')[0]
print >> sys.stderr, "NixOS version is {0}".format(version) print >> sys.stderr, "NixOS version is {0}".format(version)
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix") m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix")
m.run_command("nixos-install") m.run_command("nixos-install")
if args.hvm: if args.hvm:
m.run_command('cp /mnt/nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub') m.run_command('nix-env -iA nixos.pkgs.grub')
m.run_command('cp /nix/store/*-grub-0.97*/lib/grub/i386-pc/* /mnt/boot/grub')
m.run_command('sed -i "s|hd0|hd0,0|" /mnt/boot/grub/menu.lst') m.run_command('sed -i "s|hd0|hd0,0|" /mnt/boot/grub/menu.lst')
m.run_command('echo "(hd1) /dev/xvdg" > device.map') m.run_command('echo "(hd1) /dev/xvdg" > device.map')
m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch') m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch')
@ -98,7 +99,7 @@ def check():
m.connect() m.connect()
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0] volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
if args.hvm: if args.hvm:
instance = m._conn.run_instances( image_id="ami-6a9e4503" instance = m._conn.run_instances( image_id="ami-5f491f36"
, instance_type=instance_type , instance_type=instance_type
, key_name=args.key_name , key_name=args.key_name
, placement=m.zone , placement=m.zone
@ -185,7 +186,7 @@ f.write(
'''.format(args.region, ami_id, instance_type)) '''.format(args.region, ami_id, instance_type))
f.close() f.close()
test_depl = deployment.create_deployment(db) test_depl = db.create_deployment()
test_depl.auto_response = "y" test_depl.auto_response = "y"
test_depl.name = "ebs-creator-test" test_depl.name = "ebs-creator-test"
test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")] test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]

View File

@ -1,9 +1,8 @@
#! /bin/sh -e #! /bin/sh -e
nixos=$(nix-instantiate --find-file nixos)
export NIXOS_CONFIG=$(dirname $(readlink -f $0))/amazon-base-config.nix export NIXOS_CONFIG=$(dirname $(readlink -f $0))/amazon-base-config.nix
version=$(nix-instantiate --eval-only '<nixos>' -A config.system.nixosVersion | sed s/'"'//g) version=$(nix-instantiate --eval-only '<nixpkgs/nixos>' -A config.system.nixosVersion | sed s/'"'//g)
echo "NixOS version is $version" echo "NixOS version is $version"
buildAndUploadFor() { buildAndUploadFor() {
@ -11,13 +10,13 @@ buildAndUploadFor() {
arch="$2" arch="$2"
echo "building $system image..." echo "building $system image..."
nix-build '<nixos>' \ nix-build '<nixpkgs/nixos>' \
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami -A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \ ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
-c "$EC2_CERT" -k "$EC2_PRIVATE_KEY" -c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
for region in eu-west-1 us-east-1 us-west-1 us-west-2; do for region in eu-west-1; do
echo "uploading $system image for $region..." echo "uploading $system image for $region..."
name=nixos-$version-$arch-s3 name=nixos-$version-$arch-s3

View File

@ -131,7 +131,7 @@ in {
users.extraGroups.pulse.gid = gid; users.extraGroups.pulse.gid = gid;
systemd.services.pulseaudio = { systemd.services.pulseaudio = {
description = "PulseAudio system-wide server"; description = "PulseAudio System-Wide Server";
wantedBy = [ "sound.target" ]; wantedBy = [ "sound.target" ];
before = [ "sound.target" ]; before = [ "sound.target" ];
path = [ cfg.package ]; path = [ cfg.package ];

View File

@ -31,9 +31,9 @@ in
res = (head defs').value; res = (head defs').value;
in in
if isList res then concatLists (getValues defs') if isList res then concatLists (getValues defs')
else if builtins.lessThan 1 (length defs') then else if lessThan 1 (length defs') then
throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}." throw "The option `${showOption loc}' is defined multiple times, in ${showFiles (getFiles defs)}."
else if !builtins.isString res then else if !isString res then
throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}." throw "The option `${showOption loc}' does not have a string value, in ${showFiles (getFiles defs)}."
else res; else res;
}); });

View File

@ -6,7 +6,7 @@ let
sysctlOption = mkOptionType { sysctlOption = mkOptionType {
name = "sysctl option value"; name = "sysctl option value";
check = x: builtins.isBool x || builtins.isString x || builtins.isInt x; check = x: isBool x || isString x || isInt x;
merge = args: defs: (last defs).value; # FIXME: hacky way to allow overriding in configuration.nix. merge = args: defs: (last defs).value; # FIXME: hacky way to allow overriding in configuration.nix.
}; };
@ -46,7 +46,10 @@ in
before = [ "sysinit.target" "shutdown.target" ]; before = [ "sysinit.target" "shutdown.target" ];
wantedBy = [ "sysinit.target" "multi-user.target" ]; wantedBy = [ "sysinit.target" "multi-user.target" ];
restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ]; restartTriggers = [ config.environment.etc."sysctl.d/nixos.conf".source ];
unitConfig.DefaultDependencies = false; # needed to prevent a cycle unitConfig = {
DefaultDependencies = false; # needed to prevent a cycle
ConditionPathIsReadWrite = "/proc/sys/"; # prevent systemd-sysctl in containers
};
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;

View File

@ -188,6 +188,20 @@ in
options = [ groupOpts ]; options = [ groupOpts ];
}; };
security.initialRootPassword = mkOption {
type = types.str;
default = "";
example = "!";
description = ''
The (hashed) password for the root account set on initial
installation. The empty string denotes that root can login
locally without a password (but not via remote services such
as SSH, or indirectly via <command>su</command> or
<command>sudo</command>). The string <literal>!</literal>
prevents root from logging in using a password.
'';
};
}; };
@ -240,7 +254,23 @@ in
# Can't use useradd, since it complains that it doesn't know us # Can't use useradd, since it complains that it doesn't know us
# (bootstrap problem!). # (bootstrap problem!).
echo "root:x:0:0:System administrator:$rootHome:${config.users.defaultUserShell}" >> /etc/passwd echo "root:x:0:0:System administrator:$rootHome:${config.users.defaultUserShell}" >> /etc/passwd
echo "root::::::::" >> /etc/shadow echo "root:${config.security.initialRootPassword}:::::::" >> /etc/shadow
fi
'';
# Print a reminder for users to set a root password.
environment.interactiveShellInit =
''
if [ "$UID" = 0 ]; then
read _l < /etc/shadow
if [ "''${_l:0:6}" = root:: ]; then
cat >&2 <<EOF
Warning: Your root account has a null password, allowing local users
to login as root. Please set a non-null password using \`passwd', or
disable password-based root logins using \`passwd -l'.
EOF
fi
unset _l
fi fi
''; '';

View File

@ -1,4 +1,6 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let kernelVersion = config.boot.kernelPackages.kernel.version; in let kernelVersion = config.boot.kernelPackages.kernel.version; in
@ -8,9 +10,9 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
options = { options = {
networking.enableB43Firmware = pkgs.lib.mkOption { networking.enableB43Firmware = mkOption {
default = false; default = false;
type = pkgs.lib.types.bool; type = types.bool;
description = '' description = ''
Turn on this option if you want firmware for the NICs supported by the b43 module. Turn on this option if you want firmware for the NICs supported by the b43 module.
''; '';
@ -21,11 +23,11 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
###### implementation ###### implementation
config = pkgs.lib.mkIf config.networking.enableB43Firmware { config = mkIf config.networking.enableB43Firmware {
assertions = [ { assertions = singleton
assertion = builtins.lessThan 0 (builtins.compareVersions kernelVersion "3.2"); { assertion = lessThan 0 (builtins.compareVersions kernelVersion "3.2");
message = "b43 firmware for kernels older than 3.2 not packaged yet!"; message = "b43 firmware for kernels older than 3.2 not packaged yet!";
} ]; };
hardware.firmware = [ pkgs.b43Firmware_5_1_138 ]; hardware.firmware = [ pkgs.b43Firmware_5_1_138 ];
}; };

View File

@ -11,7 +11,7 @@ let
# CD. These are installed into the "nixos" channel of the root # CD. These are installed into the "nixos" channel of the root
# user, as expected by nixos-rebuild/nixos-install. # user, as expected by nixos-rebuild/nixos-install.
channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}" channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}"
{ expr = builtins.readFile ../../../lib/channel-expr.nix; } { expr = readFile ../../../lib/channel-expr.nix; }
'' ''
mkdir -p $out/nixos mkdir -p $out/nixos
cp -prd ${pkgs.path} $out/nixos/nixpkgs cp -prd ${pkgs.path} $out/nixos/nixpkgs

View File

@ -32,6 +32,12 @@ with pkgs.lib;
# in the Nix store on the CD. # in the Nix store on the CD.
isoImage.storeContents = [ pkgs.stdenv pkgs.busybox ]; isoImage.storeContents = [ pkgs.stdenv pkgs.busybox ];
# EFI booting
isoImage.makeEfiBootable = true;
# Add Memtest86+ to the CD. # Add Memtest86+ to the CD.
boot.loader.grub.memtest86 = true; boot.loader.grub.memtest86 = true;
# Get a console as soon as the initrd loads fbcon on EFI boot
boot.initrd.kernelModules = [ "fbcon" ];
} }

View File

@ -1,14 +0,0 @@
{ config, pkgs, ... }:
{
# Move into base image once using 3.10 or later
require = [ ./installation-cd-minimal.nix ];
boot.kernelPackages = pkgs.linuxPackages_3_10;
# Get a console as soon as the initrd loads fbcon on EFI boot
boot.initrd.kernelModules = [ "fbcon" ];
isoImage.makeEfiBootable = true;
}

View File

@ -44,31 +44,29 @@ let
# The efi boot image # The efi boot image
efiDir = pkgs.runCommand "efi-directory" {} ''
mkdir -p $out/efi/boot
cp -v ${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi $out/efi/boot/boot${targetArch}.efi
mkdir -p $out/loader/entries
echo "title NixOS LiveCD" > $out/loader/entries/nixos-livecd.conf
echo "linux /boot/bzImage" >> $out/loader/entries/nixos-livecd.conf
echo "initrd /boot/initrd" >> $out/loader/entries/nixos-livecd.conf
echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> $out/loader/entries/nixos-livecd.conf
echo "default nixos-livecd" > $out/loader/loader.conf
echo "timeout 5" >> $out/loader/loader.conf
'';
efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; } efiImg = pkgs.runCommand "efi-image_eltorito" { buildInputs = [ pkgs.mtools ]; }
'' ''
#Let's hope 10M is enough #Let's hope 10M is enough
dd bs=2048 count=5120 if=/dev/zero of="$out" dd bs=2048 count=5120 if=/dev/zero of="$out"
${pkgs.dosfstools}/sbin/mkfs.vfat "$out" ${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
mmd -i "$out" efi mcopy -svi "$out" ${efiDir}/* ::
mmd -i "$out" efi/boot mmd -i "$out" boot
mmd -i "$out" efi/nixos
mmd -i "$out" loader
mmd -i "$out" loader/entries
mcopy -v -i "$out" \ mcopy -v -i "$out" \
${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi \ ${config.boot.kernelPackages.kernel}/bzImage ::boot/bzImage
::efi/boot/boot${targetArch}.efi
mcopy -v -i "$out" \ mcopy -v -i "$out" \
${config.boot.kernelPackages.kernel}/bzImage ::bzImage ${config.system.build.initialRamdisk}/initrd ::boot/initrd
mcopy -v -i "$out" \
${config.system.build.initialRamdisk}/initrd ::efi/nixos/initrd
echo "title NixOS LiveCD" > boot-params
echo "linux /bzImage" >> boot-params
echo "initrd /efi/nixos/initrd" >> boot-params
echo "options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" >> boot-params
mcopy -v -i "$out" boot-params ::loader/entries/nixos-livecd.conf
echo "default nixos-livecd" > boot-params
echo "timeout 5" >> boot-params
mcopy -v -i "$out" boot-params ::loader/loader.conf
''; '';
targetArch = if pkgs.stdenv.isi686 then targetArch = if pkgs.stdenv.isi686 then
@ -263,6 +261,12 @@ in
{ source = efiImg; { source = efiImg;
target = "/boot/efi.img"; target = "/boot/efi.img";
} }
{ source = "${efiDir}/efi";
target = "/efi";
}
{ source = "${efiDir}/loader";
target = "/loader";
}
] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles; ] ++ mapAttrsToList (n: v: { source = v; target = "/boot/${n}"; }) config.boot.loader.grub.extraFiles;
# The Grub menu. # The Grub menu.

View File

@ -386,9 +386,6 @@ if ($showHardwareConfig) {
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
boot.loader.gummiboot.enable = true; boot.loader.gummiboot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
# !!! Remove this when nixos is on 3.10 or greater by default
# EFI booting requires kernel >= 3.10
boot.kernelPackages = pkgs.linuxPackages_3_10;
EOF EOF
} else { } else {
$bootLoaderConfig = <<EOF; $bootLoaderConfig = <<EOF;

View File

@ -106,6 +106,8 @@
firebird = 95; firebird = 95;
redis = 96; redis = 96;
haproxy = 97; haproxy = 97;
mongodb = 98;
openldap = 99;
# When adding a uid, make sure it doesn't match an existing gid. # When adding a uid, make sure it doesn't match an existing gid.
@ -140,7 +142,7 @@
tape = 25; tape = 25;
video = 26; video = 26;
dialout = 27; dialout = 27;
polkituser = 28; #polkituser = 28; # currently unused, polkitd doesn't need a group
utmp = 29; utmp = 29;
davfs2 = 31; davfs2 = 31;
privoxy = 32; privoxy = 32;
@ -193,6 +195,7 @@
amule = 90; amule = 90;
minidlna = 91; minidlna = 91;
haproxy = 92; haproxy = 92;
openldap = 93;
# When adding a gid, make sure it doesn't match an existing uid. # When adding a gid, make sure it doesn't match an existing uid.

View File

@ -53,7 +53,7 @@ with pkgs.lib;
mkDefault (if pathExists fn then readFile fn else "master"); mkDefault (if pathExists fn then readFile fn else "master");
# Note: code names must only increase in alphabetical order. # Note: code names must only increase in alphabetical order.
system.nixosCodeName = "Aardvark"; system.nixosCodeName = "Baboon";
# Generate /etc/os-release. See # Generate /etc/os-release. See
# http://0pointer.de/public/systemd-man/os-release.html for the # http://0pointer.de/public/systemd-man/os-release.html for the

View File

@ -46,7 +46,6 @@
./programs/bash/command-not-found.nix ./programs/bash/command-not-found.nix
./programs/blcr.nix ./programs/blcr.nix
./programs/environment.nix ./programs/environment.nix
./programs/gurobi.nix
./programs/info.nix ./programs/info.nix
./programs/shadow.nix ./programs/shadow.nix
./programs/shell.nix ./programs/shell.nix
@ -55,6 +54,7 @@
./programs/venus.nix ./programs/venus.nix
./programs/wvdial.nix ./programs/wvdial.nix
./programs/zsh/zsh.nix ./programs/zsh/zsh.nix
./programs/screen.nix
./rename.nix ./rename.nix
./security/apparmor.nix ./security/apparmor.nix
./security/apparmor-suid.nix ./security/apparmor-suid.nix
@ -91,6 +91,7 @@
./services/databases/virtuoso.nix ./services/databases/virtuoso.nix
./services/games/ghost-one.nix ./services/games/ghost-one.nix
./services/hardware/acpid.nix ./services/hardware/acpid.nix
./services/hardware/amd-hybrid-graphics.nix
./services/hardware/bluetooth.nix ./services/hardware/bluetooth.nix
./services/hardware/nvidia-optimus.nix ./services/hardware/nvidia-optimus.nix
./services/hardware/pcscd.nix ./services/hardware/pcscd.nix
@ -119,7 +120,6 @@
./services/misc/felix.nix ./services/misc/felix.nix
./services/misc/folding-at-home.nix ./services/misc/folding-at-home.nix
./services/misc/gpsd.nix ./services/misc/gpsd.nix
./services/misc/gurobi.nix
./services/misc/nix-daemon.nix ./services/misc/nix-daemon.nix
./services/misc/nix-gc.nix ./services/misc/nix-gc.nix
./services/misc/nixos-manual.nix ./services/misc/nixos-manual.nix
@ -247,11 +247,11 @@
./system/boot/kexec.nix ./system/boot/kexec.nix
./system/boot/loader/efi.nix ./system/boot/loader/efi.nix
./system/boot/loader/generations-dir/generations-dir.nix ./system/boot/loader/generations-dir/generations-dir.nix
./system/boot/loader/gummiboot/gummiboot.nix
./system/boot/loader/raspberrypi/raspberrypi.nix
./system/boot/loader/grub/grub.nix ./system/boot/loader/grub/grub.nix
./system/boot/loader/grub/memtest.nix ./system/boot/loader/grub/memtest.nix
./system/boot/loader/gummiboot/gummiboot.nix
./system/boot/loader/init-script/init-script.nix ./system/boot/loader/init-script/init-script.nix
./system/boot/loader/raspberrypi/raspberrypi.nix
./system/boot/luksroot.nix ./system/boot/luksroot.nix
./system/boot/modprobe.nix ./system/boot/modprobe.nix
./system/boot/shutdown.nix ./system/boot/shutdown.nix
@ -275,8 +275,10 @@
./tasks/network-interfaces.nix ./tasks/network-interfaces.nix
./tasks/scsi-link-power-management.nix ./tasks/scsi-link-power-management.nix
./tasks/swraid.nix ./tasks/swraid.nix
./testing/service-runner.nix
./virtualisation/containers.nix
./virtualisation/libvirtd.nix ./virtualisation/libvirtd.nix
#./virtualisation/nova.nix #./virtualisation/nova.nix
./virtualisation/virtualbox-guest.nix ./virtualisation/virtualbox-guest.nix
./virtualisation/xen-dom0.nix #./virtualisation/xen-dom0.nix
] ]

View File

@ -1,43 +0,0 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.programs.gurobi;
in {
options = {
programs.gurobi = {
license = mkOption {
default = null;
description = "Path to the Gurobi license file if not using a token server";
type = types.nullOr types.path;
};
tokenServerAddress = mkOption {
default = null;
description = "Address of the token server";
type = types.nullOr types.string;
};
};
};
config = mkIf (cfg.license != null || cfg.tokenServerAddress != null) {
assertions = [ {
assertion = cfg.license == null || cfg.tokenServerAddress == null;
message = "Please only set one of a gurobi license file and a gurobi token server address";
} ];
environment.variables.GRB_LICENSE_FILE = if cfg.license != null
then cfg.license
else pkgs.writeTextFile {
name = "gurobi-generated-license";
text = "TOKENSERVER=${cfg.tokenServerAddress}";
};
environment.systemPackages = [ pkgs.gurobi ];
};
}

View File

@ -0,0 +1,30 @@
{ config, pkgs, ... }:
let
inherit (pkgs.lib) mkOption mkIf types;
cfg = config.programs.screen;
in
{
###### interface
options = {
programs.screen = {
screenrc = mkOption {
default = "";
description = ''
The contents of /etc/screenrc file.
'';
type = types.lines;
};
};
};
###### implementation
config = mkIf (cfg.screenrc != "") {
environment.etc."screenrc".text = cfg.screenrc;
};
}

View File

@ -40,7 +40,7 @@ in
}; };
dates = mkOption { dates = mkOption {
default = "*:0,15,30,45"; default = "*:0/15";
type = types.string; type = types.string;
description = '' description = ''
Specification (in the format described by Specification (in the format described by
@ -161,13 +161,13 @@ in
''; '';
systemd.services.venus = systemd.services.venus =
{ description = "Planet Venus, an awesome river of news feed reader"; { description = "Planet Venus Feed Reader";
path = [ pkgs.venus ]; path = [ pkgs.venus ];
script = "exec venus-planet ${configFile}"; script = "exec venus-planet ${configFile}";
serviceConfig.User = "${cfg.user}"; serviceConfig.User = "${cfg.user}";
serviceConfig.Group = "${cfg.group}"; serviceConfig.Group = "${cfg.group}";
environment.OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt"; environment.OPENSSL_X509_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
startOn = cfg.dates; startAt = cfg.dates;
}; };
}; };

View File

@ -18,42 +18,32 @@ in
description = "Whether to enable PolKit."; description = "Whether to enable PolKit.";
}; };
security.polkit.permissions = mkOption { security.polkit.extraConfig = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
example = example =
'' ''
[Disallow Users To Suspend] /* Log authorization checks. */
Identity=unix-group:users polkit.addRule(function(action, subject) {
Action=org.freedesktop.upower.* polkit.log("user " + subject.user + " is attempting action " + action.id + " from PID " + subject.pid);
ResultAny=no });
ResultInactive=no
ResultActive=no
[Allow Anybody To Eject Disks] /* Allow any local user to do anything (dangerous!). */
Identity=unix-user:* polkit.addRule(function(action, subject) {
Action=org.freedesktop.udisks.drive-eject if (subject.local) return "yes";
ResultAny=yes });
ResultInactive=yes
ResultActive=yes
[Allow Alice To Mount Filesystems After Admin Authentication]
Identity=unix-user:alice
Action=org.freedesktop.udisks.filesystem-mount
ResultAny=auth_admin
ResultInactive=auth_admin
ResultActive=auth_admin
''; '';
description = description =
'' ''
Allows the default permissions of privileged actions to be overridden. Any polkit rules to be added to config (in JavaScript ;-). See:
http://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html#polkit-rules
''; '';
}; };
security.polkit.adminIdentities = mkOption { security.polkit.adminIdentities = mkOption {
type = types.str; type = types.listOf types.str;
default = "unix-user:0;unix-group:wheel"; default = [ "unix-user:0" "unix-group:wheel" ];
example = ""; example = [ "unix-user:alice" "unix-group:admin" ];
description = description =
'' ''
Specifies which users are considered administrators, for those Specifies which users are considered administrators, for those
@ -71,29 +61,20 @@ in
environment.systemPackages = [ pkgs.polkit ]; environment.systemPackages = [ pkgs.polkit ];
# The polkit daemon reads action files systemd.packages = [ pkgs.polkit ];
environment.pathsToLink = [ "/share/polkit-1/actions" ];
environment.etc = # The polkit daemon reads action/rule files
[ # No idea what the "null backend" is, but it seems to need this. environment.pathsToLink = [ "/share/polkit-1" ];
{ source = "${pkgs.polkit}/etc/polkit-1/nullbackend.conf.d";
target = "polkit-1/nullbackend.conf.d";
}
# This file determines what users are considered # PolKit rules for NixOS.
# "administrators". environment.etc."polkit-1/rules.d/10-nixos.rules".text =
{ source = pkgs.writeText "10-nixos.conf" ''
'' polkit.addAdminRule(function(action, subject) {
[Configuration] return [${concatStringsSep ", " (map (i: "\"${i}\"") cfg.adminIdentities)}];
AdminIdentities=${cfg.adminIdentities} });
'';
target = "polkit-1/localauthority.conf.d/10-nixos.conf";
}
{ source = pkgs.writeText "org.nixos.pkla" cfg.permissions; ${cfg.extraConfig}
target = "polkit-1/localauthority/10-vendor.d/org.nixos.pkla"; ''; #TODO: validation on compilation (at least against typos)
}
];
services.dbus.packages = [ pkgs.polkit ]; services.dbus.packages = [ pkgs.polkit ];
@ -101,24 +82,31 @@ in
security.setuidPrograms = [ "pkexec" ]; security.setuidPrograms = [ "pkexec" ];
security.setuidOwners = singleton security.setuidOwners = [
{ program = "polkit-agent-helper-1"; { program = "polkit-agent-helper-1";
owner = "root"; owner = "root";
group = "root"; group = "root";
setuid = true; setuid = true;
source = "${pkgs.polkit}/libexec/polkit-1/polkit-agent-helper-1"; source = "${pkgs.polkit}/lib/polkit-1/polkit-agent-helper-1";
}; }
];
system.activationScripts.polkit = system.activationScripts.polkit =
'' ''
mkdir -p /var/lib/polkit-1/localauthority # Probably no more needed, clean up
chmod 700 /var/lib/polkit-1{/localauthority,} rm -rf /var/lib/{polkit-1,PolicyKit}
# Force polkitd to be restarted so that it reloads its # Force polkitd to be restarted so that it reloads its
# configuration. # configuration.
${pkgs.procps}/bin/pkill -INT -u root -x polkitd ${pkgs.procps}/bin/pkill -INT -u root -x polkitd
''; '';
users.extraUsers.polkituser = {
description = "PolKit daemon";
uid = config.ids.uids.polkituser;
};
}; };
} }

View File

@ -55,6 +55,7 @@ in
{ description = "Store Sound Card State"; { description = "Store Sound Card State";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
unitConfig.RequiresMountsFor = "/var/lib/alsa"; unitConfig.RequiresMountsFor = "/var/lib/alsa";
unitConfig.ConditionVirtualization = "!systemd-nspawn";
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;

View File

@ -90,8 +90,9 @@ in
config = mkIf config.services.mongodb.enable { config = mkIf config.services.mongodb.enable {
users.extraUsers = singleton users.extraUsers.mongodb = mkIf (cfg.user == "mongodb")
{ name = cfg.user; { name = "mongodb";
uid = config.ids.uids.mongodb;
description = "MongoDB server user"; description = "MongoDB server user";
}; };

View File

@ -26,6 +26,16 @@ in
"; ";
}; };
user = mkOption {
default = "openldap";
description = "User account under which slapd runs.";
};
group = mkOption {
default = "openldap";
description = "Group account under which slapd runs.";
};
extraConfig = mkOption { extraConfig = mkOption {
default = ""; default = "";
description = " description = "
@ -49,10 +59,23 @@ in
after = [ "network.target" ]; after = [ "network.target" ];
preStart = '' preStart = ''
mkdir -p /var/run/slapd mkdir -p /var/run/slapd
chown -R ${cfg.user}:${cfg.group} /var/run/slapd
mkdir -p /var/db/openldap
chown -R ${cfg.user}:${cfg.group} /var/db/openldap
''; '';
serviceConfig.ExecStart = "${openldap}/libexec/slapd -d 0 -f ${configFile}"; serviceConfig.ExecStart = "${openldap}/libexec/slapd -u openldap -g openldap -d 0 -f ${configFile}";
}; };
}; users.extraUsers = optionalAttrs (cfg.user == "openldap") (singleton
{ name = "openldap";
group = "openldap";
uid = config.ids.uids.openldap;
});
users.extraGroups = optionalAttrs (cfg.group == "openldap") (singleton
{ name = "openldap";
gid = config.ids.gids.openldap;
});
};
} }

View File

@ -30,6 +30,7 @@ let
hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}' hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}'
ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}' ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
log_destination = 'stderr' log_destination = 'stderr'
port = ${toString cfg.port}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
@ -63,9 +64,9 @@ in
port = mkOption { port = mkOption {
type = types.int; type = types.int;
default = "5432"; default = 5432;
description = '' description = ''
Port for PostgreSQL. The port on which PostgreSQL listens.
''; '';
}; };
@ -105,7 +106,9 @@ in
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
Whether to run PostgreSQL with -i flag to enable TCP/IP connections. Whether PostgreSQL should listen on all network interfaces.
If disabled, the database can only be accessed via its Unix
domain socket or via TCP connections to localhost.
''; '';
}; };
@ -181,8 +184,13 @@ in
# Initialise the database. # Initialise the database.
if ! test -e ${cfg.dataDir}; then if ! test -e ${cfg.dataDir}; then
mkdir -m 0700 -p ${cfg.dataDir} mkdir -m 0700 -p ${cfg.dataDir}
chown -R postgres ${cfg.dataDir} if [ "$(id -u)" = 0 ]; then
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root' chown -R postgres ${cfg.dataDir}
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
else
# For non-root operation.
initdb
fi
rm -f ${cfg.dataDir}/*.conf rm -f ${cfg.dataDir}/*.conf
touch "${cfg.dataDir}/.first_startup" touch "${cfg.dataDir}/.first_startup"
fi fi
@ -203,6 +211,7 @@ in
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See # Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
# http://www.postgresql.org/docs/current/static/server-shutdown.html # http://www.postgresql.org/docs/current/static/server-shutdown.html
KillSignal = "SIGINT"; KillSignal = "SIGINT";
KillMode = "process"; # FIXME: this may cause processes to be left behind in the cgroup even after the final SIGKILL
# Give Postgres a decent amount of time to clean up after # Give Postgres a decent amount of time to clean up after
# receiving systemd's SIGINT. # receiving systemd's SIGINT.

View File

@ -110,6 +110,7 @@ in
exec = "acpid --confdir ${acpiConfDir}"; exec = "acpid --confdir ${acpiConfDir}";
unitConfig.ConditionVirtualization = "!systemd-nspawn";
unitConfig.ConditionPathExists = [ "/proc/acpi" ]; unitConfig.ConditionPathExists = [ "/proc/acpi" ];
}; };

View File

@ -0,0 +1,39 @@
{ config, pkgs, ... }:
{
###### interface
options = {
hardware.amdHybridGraphics.disable = pkgs.lib.mkOption {
default = false;
type = pkgs.lib.types.bool;
description = ''
Completely disable the AMD graphics card and use the
integrated graphics processor instead.
'';
};
};
###### implementation
config = pkgs.lib.mkIf config.hardware.amdHybridGraphics.disable {
systemd.services."amd-hybrid-graphics" = {
path = [ pkgs.bash ];
description = "Disable AMD Card";
after = [ "sys-kernel-debug.mount" ];
requires = [ "sys-kernel-debug.mount" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.bash}/bin/sh -c 'echo -e \"IGD\\nOFF\" > /sys/kernel/debug/vgaswitcheroo/switch; exit 0'";
ExecStop = "${pkgs.bash}/bin/sh -c 'echo ON >/sys/kernel/debug/vgaswitcheroo/switch; exit 0'";
};
};
};
}

View File

@ -28,7 +28,7 @@ with pkgs.lib;
services.dbus.packages = [ pkgs.bluez ]; services.dbus.packages = [ pkgs.bluez ];
systemd.services."dbus-org.bluez" = { systemd.services."dbus-org.bluez" = {
description = "Bluetooth service"; description = "Bluetooth Service";
serviceConfig = { serviceConfig = {
Type = "dbus"; Type = "dbus";
BusName = "org.bluez"; BusName = "org.bluez";

View File

@ -209,7 +209,7 @@ in
###### implementation ###### implementation
config = { config = mkIf (!config.boot.isContainer) {
services.udev.extraRules = nixosRules; services.udev.extraRules = nixosRules;
@ -231,9 +231,16 @@ in
boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}"; boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}";
system.activationScripts.clearHotplug = system.activationScripts.udevd =
'' ''
echo "" > /proc/sys/kernel/hotplug echo "" > /proc/sys/kernel/hotplug
# Regenerate the hardware database /var/lib/udev/hwdb.bin
# whenever systemd changes.
if [ ! -e /var/lib/udev/prev-systemd -o "$(readlink /var/lib/udev/prev-systemd)" != ${config.systemd.package} ]; then
echo "regenerating udev hardware database..."
${config.systemd.package}/bin/udevadm hwdb --update && ln -sfn ${config.systemd.package} /var/lib/udev/prev-systemd
fi
''; '';
}; };

View File

@ -32,6 +32,8 @@ with pkgs.lib;
path = [ pkgs.sysklogd ]; path = [ pkgs.sysklogd ];
unitConfig.ConditionVirtualization = "!systemd-nspawn";
exec = exec =
"klogd -c 1 -2 -n " + "klogd -c 1 -2 -n " +
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map"; "-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";

View File

@ -3,72 +3,8 @@
with pkgs.lib; with pkgs.lib;
let let
cfg = config.services.logstash; cfg = config.services.logstash;
listToConfig = list: "[ " + (concatStringsSep ", " (map exprToConfig list)) + " ]";
hashToConfig = attrs:
let
attrNameToConfigList = name:
[ (exprToConfig name) (exprToConfig (getAttr name attrs)) ];
in
"[ " +
(concatStringsSep ", " (map attrNameToConfigList (attrNames attrs))) +
" ]";
valueToConfig = nvpair: let name = nvpair.name; value = nvpair.value; in
if (isAttrs value) && ((!(value ? __type)) || value.__type == "repeated")
then ''
${name} {
${exprToConfig value}
}
''
else "${name} => ${exprToConfig value}";
repeatedAttrsToConfig = values:
concatStringsSep "\n" (map valueToConfig values);
attrsToConfig = attrs:
let
attrToConfig = name: valueToConfig {
inherit name;
value = (getAttr name attrs);
};
in
concatStringsSep "\n" (map attrToConfig (attrNames attrs));
exprToConfig = expr:
let
isCustomType = expr: (isAttrs expr) && (expr ? __type);
isFloat = expr: (isCustomType expr) && (expr.__type == "float");
isHash = expr: (isCustomType expr) && (expr.__type == "hash");
isRepeatedAttrs = expr: (isCustomType expr) && (expr.__type == "repeated");
in
if builtins.isBool expr then (if expr then "true" else "false") else
if builtins.isString expr then ''"${expr}"'' else
if builtins.isInt expr then toString expr else
if isFloat expr then expr.value else
if isList expr then listToConfig expr else
if isHash expr then hashToConfig expr.value else
if isRepeatedAttrs expr then repeatedAttrsToConfig expr.values
else attrsToConfig expr;
mergeConfigs = configs:
let
op = attrs: newAttrs:
let
isRepeated = newAttrs ? __type && newAttrs.__type == "repeated";
in {
values = attrs.values ++ (if isRepeated then newAttrs.values else
map (name: { inherit name; value = getAttr name newAttrs; })
(attrNames newAttrs));
};
in (foldl op { values = []; } configs) // { __type = "repeated"; };
in in
{ {
@ -78,48 +14,45 @@ in
services.logstash = { services.logstash = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = '' description = "Enable logstash";
Enable logstash.
'';
}; };
inputConfig = mkOption { inputConfig = mkOption {
default = {}; default = ''stdin { type => "example" }'';
description = '' description = "Logstash input configuration";
An attribute set (or an expression generated by mkNameValuePairs) example = ''
representing a logstash configuration's input section. # Read from journal
Logstash configs are name-value pairs, where values can be bools, pipe {
strings, numbers, arrays, hashes, or other name-value pairs, command => "${pkgs.systemd}/bin/journalctl -f -o json"
and names are strings that can be repeated. Name-value pairs with no type => "syslog" codec => json {}
repeats are represented by attr sets. Bools, strings, ints, and }
arrays are mapped directly. Name-value pairs with repeats can be
generated by the config.lib.logstash.mkNameValuePairs function, which
takes a list of attrsets and combines them while preserving attribute
name duplicates if they occur. Similarly, there are the mkFloat and
mkHash functions, which take a string representation of a float and an
attrset, respectively.
''; '';
apply = mergeConfigs;
}; };
filterConfig = mkOption { filterConfig = mkOption {
default = {}; default = ''noop {}'';
description = '' description = "logstash filter configuration";
An attribute set (or an expression generated by mkNameValuePairs) example = ''
representing a logstash configuration's filter section. if [type] == "syslog" {
See inputConfig description for details. # Keep only relevant systemd fields
# http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
prune {
whitelist_names => [
"type", "@timestamp", "@version",
"MESSAGE", "PRIORITY", "SYSLOG_FACILITY",
]
}
}
''; '';
apply = mergeConfigs;
}; };
outputConfig = mkOption { outputConfig = mkOption {
default = {}; default = ''stdout { debug => true debug_format => "json"}'';
description = '' description = "Logstash output configuration";
An attribute set (or an expression generated by mkNameValuePairs) example = ''
representing a logstash configuration's output section. redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
See inputConfig description for details. elasticsearch { embedded => true }
''; '';
apply = mergeConfigs;
}; };
}; };
}; };
@ -127,35 +60,26 @@ in
###### implementation ###### implementation
config = mkMerge [ { config = mkIf cfg.enable {
lib.logstash = {
mkFloat = stringRep: { __type = "float"; value = stringRep; };
mkHash = attrs: { __type = "hash"; value = attrs; };
mkNameValuePairs = mergeConfigs;
};
} ( mkIf cfg.enable {
systemd.services.logstash = with pkgs; { systemd.services.logstash = with pkgs; {
description = "Logstash daemon"; description = "Logstash daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ jre ]; serviceConfig = {
ExecStart = "${jre}/bin/java -jar ${logstash} agent -f ${writeText "logstash.conf" ''
input {
${cfg.inputConfig}
}
script = "cd /tmp && exec java -jar ${logstash} agent -f ${writeText "logstash.conf" '' filter {
input { ${cfg.filterConfig}
${exprToConfig cfg.inputConfig} }
}
filter { output {
${exprToConfig cfg.filterConfig} ${cfg.outputConfig}
} }
''}";
output { };
${exprToConfig cfg.outputConfig}
}
''} &> /var/log/logstash.log";
}; };
})]; };
} }

View File

@ -15,6 +15,7 @@ let
enablePostgreSQLDatabase = config.services.postgresql.enable; enablePostgreSQLDatabase = config.services.postgresql.enable;
enableSubversionRepository = config.services.svnserve.enable; enableSubversionRepository = config.services.svnserve.enable;
enableTomcatWebApplication = config.services.tomcat.enable; enableTomcatWebApplication = config.services.tomcat.enable;
enableMongoDatabase = config.services.mongodb.enable;
}); });
in in
@ -110,7 +111,7 @@ in
// optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; } // optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; }
// optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; } // optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; }
// optionalAttrs (cfg.publishInfrastructure.enableAuthentication) ( // optionalAttrs (cfg.publishInfrastructure.enableAuthentication) (
optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = builtins.readFile config.services.mysql.rootPassword; }) optionalAttrs (config.services.mysql.enable) { mysqlUsername = "root"; mysqlPassword = readFile config.services.mysql.rootPassword; })
) )
; ;
@ -125,17 +126,18 @@ in
++ optional config.services.httpd.enable "httpd.service" ++ optional config.services.httpd.enable "httpd.service"
++ optional config.services.mysql.enable "mysql.service" ++ optional config.services.mysql.enable "mysql.service"
++ optional config.services.tomcat.enable "tomcat.service" ++ optional config.services.tomcat.enable "tomcat.service"
++ optional config.services.svnserve.enable "svnserve.service"; ++ optional config.services.svnserve.enable "svnserve.service"
++ optional config.services.mongodb.enable "mongodb.service";
restartIfChanged = false; restartIfChanged = false;
path = [ pkgs.nix pkgs.disnix ]; path = [ pkgs.nix pkgs.disnix pkgs.dysnomia ];
script = environment = {
'' HOME = "/root";
export HOME=/root };
disnix-service --dysnomia-modules-dir=${dysnomia}/libexec/dysnomia
''; exec = "disnix-service";
}; };
} // optionalAttrs cfg.publishAvahi { } // optionalAttrs cfg.publishAvahi {
disnixAvahi = disnixAvahi =
@ -150,7 +152,7 @@ in
${concatMapStrings (infrastructureAttrName: ${concatMapStrings (infrastructureAttrName:
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure); let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
in in
if builtins.isInt infrastructureAttrValue then if isInt infrastructureAttrValue then
''${infrastructureAttrName}=${toString infrastructureAttrValue} \ ''${infrastructureAttrName}=${toString infrastructureAttrValue} \
'' ''
else else

View File

@ -1,41 +0,0 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.gurobi.tokenServer;
in {
options = {
services.gurobi.tokenServer = {
enable = mkOption {
default = false;
description = "Whether to enable the Gurobi token server";
type = types.bool;
};
license = mkOption {
description = "Path to the Gurobi license file";
type = types.path;
};
};
};
config = mkIf cfg.enable {
systemd.services.gurobi-token-server = {
description = "Gurobi token server";
wantedBy = [ "multi-user.target" ];
environment.GRB_LICENSE_FILE = cfg.license;
serviceConfig = {
ExecStart = "${pkgs.gurobi}/bin/grb_ts";
Type = "forking";
};
};
};
}

View File

@ -279,6 +279,7 @@ in
{ description = "Nix Daemon Socket"; { description = "Nix Daemon Socket";
wantedBy = [ "sockets.target" ]; wantedBy = [ "sockets.target" ];
before = [ "multi-user.target" ]; before = [ "multi-user.target" ];
unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket/";
socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket"; socketConfig.ListenStream = "/nix/var/nix/daemon-socket/socket";
}; };
@ -290,6 +291,8 @@ in
environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; }; environment = cfg.envVars // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-bundle.crt"; };
unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket/";
serviceConfig = serviceConfig =
{ ExecStart = "@${nix}/bin/nix-daemon nix-daemon --daemon"; { ExecStart = "@${nix}/bin/nix-daemon nix-daemon --daemon";
KillMode = "process"; KillMode = "process";
@ -331,10 +334,8 @@ in
'' ''
# Set up secure multi-user builds: non-root users build through the # Set up secure multi-user builds: non-root users build through the
# Nix daemon. # Nix daemon.
if test "$USER" != root; then if [ "$USER" != root -o ! -w /nix/var/nix/db ]; then
export NIX_REMOTE=daemon export NIX_REMOTE=daemon
else
export NIX_REMOTE=
fi fi
''; '';

View File

@ -23,6 +23,7 @@ let
manual = import ../../../doc/manual { manual = import ../../../doc/manual {
inherit pkgs; inherit pkgs;
version = config.system.nixosVersion;
revision = config.system.nixosRevision; revision = config.system.nixosRevision;
options = eval.options; options = eval.options;
}; };

View File

@ -148,7 +148,7 @@ in
# wall: cannot get tty name: Inappropriate ioctl for device # wall: cannot get tty name: Inappropriate ioctl for device
# The message still gets through. # The message still gets through.
systemd.services.apcupsd = { systemd.services.apcupsd = {
description = "APC UPS daemon"; description = "APC UPS Daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
preStart = "mkdir -p /run/apcupsd/"; preStart = "mkdir -p /run/apcupsd/";
serviceConfig = { serviceConfig = {
@ -172,7 +172,7 @@ in
before = [ "final.target" ]; before = [ "final.target" ];
wantedBy = [ "shutdown.target" ]; wantedBy = [ "shutdown.target" ];
unitConfig = { unitConfig = {
Description = "APC UPS killpower"; Description = "APC UPS Kill Power";
ConditionPathExists = "/run/apcupsd/powerfail"; ConditionPathExists = "/run/apcupsd/powerfail";
DefaultDependencies = "no"; DefaultDependencies = "no";
}; };

View File

@ -62,6 +62,8 @@ in {
ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground"; ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
User = "dd-agent"; User = "dd-agent";
Group = "dd-agent"; Group = "dd-agent";
Restart = "always";
RestartSec = 2;
}; };
restartTriggers = [ pkgs.dd-agent datadog_conf ]; restartTriggers = [ pkgs.dd-agent datadog_conf ];
}; };
@ -76,6 +78,8 @@ in {
Group = "dd-agent"; Group = "dd-agent";
Type = "forking"; Type = "forking";
PIDFile = "/tmp/dogstatsd.pid"; PIDFile = "/tmp/dogstatsd.pid";
Restart = "always";
RestartSec = 2;
}; };
restartTriggers = [ pkgs.dd-agent datadog_conf ]; restartTriggers = [ pkgs.dd-agent datadog_conf ];
}; };

View File

@ -15,6 +15,7 @@ let
PYTHONPATH = "${pkgs.python27Packages.carbon}/lib/python2.7/site-packages"; PYTHONPATH = "${pkgs.python27Packages.carbon}/lib/python2.7/site-packages";
GRAPHITE_ROOT = dataDir; GRAPHITE_ROOT = dataDir;
GRAPHITE_CONF_DIR = "/etc/graphite/"; GRAPHITE_CONF_DIR = "/etc/graphite/";
GRAPHITE_STORAGE_DIR = dataDir;
}; };
in { in {
@ -171,7 +172,7 @@ in {
]; ];
systemd.services.carbonCache = mkIf cfg.carbon.enableCache { systemd.services.carbonCache = mkIf cfg.carbon.enableCache {
description = "Graphite data storage backend"; description = "Graphite Data Storage Backend";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment = carbonEnv; environment = carbonEnv;
@ -189,7 +190,7 @@ in {
}; };
systemd.services.carbonAggregator = mkIf cfg.carbon.enableAggregator { systemd.services.carbonAggregator = mkIf cfg.carbon.enableAggregator {
description = "Carbon data aggregator"; description = "Carbon Data Aggregator";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment = carbonEnv; environment = carbonEnv;
@ -200,7 +201,7 @@ in {
}; };
systemd.services.carbonRelay = mkIf cfg.carbon.enableRelay { systemd.services.carbonRelay = mkIf cfg.carbon.enableRelay {
description = "Carbon data relay"; description = "Carbon Data Relay";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment = carbonEnv; environment = carbonEnv;
@ -211,7 +212,7 @@ in {
}; };
systemd.services.graphiteWeb = mkIf cfg.web.enable { systemd.services.graphiteWeb = mkIf cfg.web.enable {
description = "Graphite web interface"; description = "Graphite Web Interface";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];
environment = { environment = {

View File

@ -182,7 +182,7 @@ in
}) (mkIf nodeCfg.enable { }) (mkIf nodeCfg.enable {
systemd.services.munin-node = { systemd.services.munin-node = {
description = "Munin node, the agent process"; description = "Munin Node";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pkgs.munin ]; path = [ pkgs.munin ];

View File

@ -57,7 +57,7 @@ let
nssModulesPath = config.system.nssModules.path; nssModulesPath = config.system.nssModules.path;
daemonService = appName: args: daemonService = appName: args:
{ description = "Samba Service daemon ${appName}"; { description = "Samba Service Daemon ${appName}";
wantedBy = [ "samba.target" ]; wantedBy = [ "samba.target" ];
partOf = [ "samba.target" ]; partOf = [ "samba.target" ];
@ -211,7 +211,7 @@ in
systemd = { systemd = {
targets.samba = { targets.samba = {
description = "Samba server"; description = "Samba Server";
requires = [ "samba-setup.service" ]; requires = [ "samba-setup.service" ];
after = [ "samba-setup.service" "network.target" ]; after = [ "samba-setup.service" "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
@ -222,7 +222,7 @@ in
"samba-smbd" = daemonService "smbd" "-F"; "samba-smbd" = daemonService "smbd" "-F";
"samba-winbindd" = daemonService "winbindd" "-F"; "samba-winbindd" = daemonService "winbindd" "-F";
"samba-setup" = { "samba-setup" = {
description = "Samba setup task"; description = "Samba Setup Task";
script = setupScript; script = setupScript;
unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba"; unitConfig.RequiresMountsFor = "/home/smbd /var/samba /var/log/samba";
}; };

View File

@ -114,6 +114,8 @@ in
path = [ dhcpcd pkgs.nettools pkgs.openresolv ]; path = [ dhcpcd pkgs.nettools pkgs.openresolv ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
serviceConfig = serviceConfig =
{ Type = "forking"; { Type = "forking";
PIDFile = "/run/dhcpcd.pid"; PIDFile = "/run/dhcpcd.pid";

View File

@ -21,7 +21,7 @@ let
level=WARN level=WARN
''; '';
polkitConf = '' /*
[network-manager] [network-manager]
Identity=unix-group:networkmanager Identity=unix-group:networkmanager
Action=org.freedesktop.NetworkManager.* Action=org.freedesktop.NetworkManager.*
@ -35,6 +35,17 @@ let
ResultAny=yes ResultAny=yes
ResultInactive=no ResultInactive=no
ResultActive=yes ResultActive=yes
*/
polkitConf = ''
polkit.addRule(function(action, subject) {
if (
subject.isInGroup("networkmanager")
&& subject.active
&& (action.id.indexOf("org.freedesktop.NetworkManager.") == 0
|| action.id.indexOf("org.freedesktop.ModemManager.") == 0
))
{ return polkit.Result.YES; }
});
''; '';
ipUpScript = writeScript "01nixos-ip-up" '' ipUpScript = writeScript "01nixos-ip-up" ''
@ -44,15 +55,19 @@ let
fi fi
''; '';
ns = xs: writeText "nameservers" (
concatStrings (map (s: "nameserver ${s}\n") xs)
);
overrideNameserversScript = writeScript "02overridedns" '' overrideNameserversScript = writeScript "02overridedns" ''
#!/bin/sh #!/bin/sh
${optionalString cfg.overrideNameservers "${gnused}/bin/sed -i '/nameserver /d' /etc/resolv.conf"} tmp=`${coreutils}/bin/mktemp`
${concatStrings (map (s: '' ${gnused}/bin/sed '/nameserver /d' /etc/resolv.conf > $tmp
${optionalString cfg.appendNameservers ${gnugrep}/bin/grep 'nameserver ' /etc/resolv.conf | \
"${gnused}/bin/sed -i '/nameserver ${s}/d' /etc/resolv.conf" ${gnugrep}/bin/grep -vf ${ns (cfg.appendNameservers ++ cfg.insertNameservers)} > $tmp.ns
} ${optionalString (cfg.appendNameservers != []) "${coreutils}/bin/cat $tmp $tmp.ns ${ns cfg.appendNameservers} > /etc/resolv.conf"}
echo 'nameserver ${s}' >> /etc/resolv.conf ${optionalString (cfg.insertNameservers != []) "${coreutils}/bin/cat $tmp ${ns cfg.insertNameservers} $tmp.ns > /etc/resolv.conf"}
'') config.networking.nameservers)} ${coreutils}/bin/rm -f $tmp $tmp.ns
''; '';
in { in {
@ -84,23 +99,21 @@ in {
apply = list: [ networkmanager modemmanager wpa_supplicant ] ++ list; apply = list: [ networkmanager modemmanager wpa_supplicant ] ++ list;
}; };
overrideNameservers = mkOption { appendNameservers = mkOption {
default = false; type = types.listOf types.string;
default = [];
description = '' description = ''
If enabled, any nameservers received by DHCP or configured in A list of name servers that should be appended
NetworkManager will be replaced by the nameservers configured to the ones configured in NetworkManager or received by DHCP.
in the <literal>networking.nameservers</literal> option. This
option overrides the <literal>appendNameservers</literal> option
if both are enabled.
''; '';
}; };
appendNameservers = mkOption { insertNameservers = mkOption {
default = false; type = types.listOf types.string;
default = [];
description = '' description = ''
If enabled, the name servers configured in the A list of name servers that should be inserted before
<literal>networking.nameservers</literal> option will be appended the ones configured in NetworkManager or received by DHCP.
to the ones configured in NetworkManager or received by DHCP.
''; '';
}; };
@ -133,7 +146,7 @@ in {
{ source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name"; { source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
target = "NetworkManager/VPN/nm-openconnect-service.name"; target = "NetworkManager/VPN/nm-openconnect-service.name";
} }
] ++ pkgs.lib.optional (cfg.overrideNameservers || cfg.appendNameservers) ] ++ pkgs.lib.optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
{ source = overrideNameserversScript; { source = overrideNameserversScript;
target = "NetworkManager/dispatcher.d/02overridedns"; target = "NetworkManager/dispatcher.d/02overridedns";
}; };
@ -179,7 +192,7 @@ in {
systemctl restart NetworkManager systemctl restart NetworkManager
''; '';
security.polkit.permissions = polkitConf; security.polkit.extraConfig = polkitConf;
# openvpn plugin has only dbus interface # openvpn plugin has only dbus interface
services.dbus.packages = cfg.packages ++ [ services.dbus.packages = cfg.packages ++ [

View File

@ -19,7 +19,7 @@ let
knownHostsFile = pkgs.writeText "ssh_known_hosts" ( knownHostsFile = pkgs.writeText "ssh_known_hosts" (
flip concatMapStrings knownHosts (h: flip concatMapStrings knownHosts (h:
"${concatStringsSep "," h.hostNames} ${builtins.readFile h.publicKeyFile}" "${concatStringsSep "," h.hostNames} ${readFile h.publicKeyFile}"
) )
); );
@ -59,7 +59,7 @@ let
mode = "0444"; mode = "0444";
source = pkgs.writeText "${u.name}-authorized_keys" '' source = pkgs.writeText "${u.name}-authorized_keys" ''
${concatStringsSep "\n" u.openssh.authorizedKeys.keys} ${concatStringsSep "\n" u.openssh.authorizedKeys.keys}
${concatMapStrings (f: builtins.readFile f + "\n") u.openssh.authorizedKeys.keyFiles} ${concatMapStrings (f: readFile f + "\n") u.openssh.authorizedKeys.keyFiles}
''; '';
}; };
usersWithKeys = attrValues (flip filterAttrs config.users.extraUsers (n: u: usersWithKeys = attrValues (flip filterAttrs config.users.extraUsers (n: u:

View File

@ -24,6 +24,7 @@ let
cfgText = "${vsftpdName}=${if getAttr nixosName cfg then "YES" else "NO"}"; cfgText = "${vsftpdName}=${if getAttr nixosName cfg then "YES" else "NO"}";
nixosOption = { nixosOption = {
type = types.bool;
name = nixosName; name = nixosName;
value = mkOption { value = mkOption {
inherit description default; inherit description default;
@ -33,27 +34,26 @@ let
}; };
optionDescription = [ optionDescription = [
(yesNoOption "anonymousUser" "anonymous_enable" false '' (yesNoOption "anonymousUser" "anonymous_enable" false ''
Whether to enable the anonymous FTP user. Whether to enable the anonymous FTP user.
'') '')
(yesNoOption "localUsers" "local_enable" false '' (yesNoOption "localUsers" "local_enable" false ''
Whether to enable FTP for local users. Whether to enable FTP for local users.
'') '')
(yesNoOption "writeEnable" "write_enable" false '' (yesNoOption "writeEnable" "write_enable" false ''
Whether any write activity is permitted to users. Whether any write activity is permitted to users.
'') '')
(yesNoOption "anonymousUploadEnable" "anon_upload_enable" false '' (yesNoOption "anonymousUploadEnable" "anon_upload_enable" false ''
Whether any uploads are permitted to anonymous users. Whether any uploads are permitted to anonymous users.
'') '')
(yesNoOption "anonymousMkdirEnable" "anon_mkdir_write_enable" false '' (yesNoOption "anonymousMkdirEnable" "anon_mkdir_write_enable" false ''
Whether any uploads are permitted to anonymous users. Whether any uploads are permitted to anonymous users.
'') '')
(yesNoOption "chrootlocalUser" "chroot_local_user" false '' (yesNoOption "chrootlocalUser" "chroot_local_user" false ''
Whether local users are confined to their home directory. Whether local users are confined to their home directory.
'') '')
(yesNoOption "userlistEnable" "userlist_enable" false '' (yesNoOption "userlistEnable" "userlist_enable" false ''
Whether users are included. Whether users are included.
'') '')
(yesNoOption "userlistDeny" "userlist_deny" false '' (yesNoOption "userlistDeny" "userlist_deny" false ''
Specifies whether <option>userlistFile</option> is a list of user Specifies whether <option>userlistFile</option> is a list of user
@ -61,35 +61,37 @@ let
The default <literal>false</literal> means whitelist/allow. The default <literal>false</literal> means whitelist/allow.
'') '')
(yesNoOption "forceLocalLoginsSSL" "force_local_logins_ssl" false '' (yesNoOption "forceLocalLoginsSSL" "force_local_logins_ssl" false ''
Only applies if <option>sslEnable</option> is true. Non anonymous (local) users Only applies if <option>sslEnable</option> is true. Non anonymous (local) users
must use a secure SSL connection to send a password. must use a secure SSL connection to send a password.
'') '')
(yesNoOption "forceLocalDataSSL" "force_local_data_ssl" false '' (yesNoOption "forceLocalDataSSL" "force_local_data_ssl" false ''
Only applies if <option>sslEnable</option> is true. Non anonymous (local) users Only applies if <option>sslEnable</option> is true. Non anonymous (local) users
must use a secure SSL connection for sending/receiving data on data connection. must use a secure SSL connection for sending/receiving data on data connection.
'') '')
(yesNoOption "ssl_tlsv1" "ssl_tlsv1" true '' '') (yesNoOption "ssl_tlsv1" "ssl_tlsv1" true '' '')
(yesNoOption "ssl_sslv2" "ssl_sslv2" false '' '') (yesNoOption "ssl_sslv2" "ssl_sslv2" false '' '')
(yesNoOption "ssl_sslv3" "ssl_sslv3" false '' '') (yesNoOption "ssl_sslv3" "ssl_sslv3" false '' '')
];
{ configFile = pkgs.writeText "vsftpd.conf"
cfgText = if cfg.rsaCertFile == null then "" ''
else '' ${concatMapStrings (x: "${x.cfgText}\n") optionDescription}
${optionalString (cfg.rsaCertFile != null) ''
ssl_enable=YES ssl_enable=YES
rsa_cert_file=${cfg.rsaCertFile} rsa_cert_file=${cfg.rsaCertFile}
''; ''}
${optionalString (cfg.userlistFile != null) ''
nixosOption = { userlist_file=${cfg.userlistFile}
name = "rsaCertFile"; ''}
value = mkOption { background=YES
default = null; listen=YES
description = '' nopriv_user=vsftpd
rsa certificate file. secure_chroot_dir=/var/empty
''; syslog_enable=YES
}; ${optionalString (pkgs.stdenv.system == "x86_64-linux") ''
}; seccomp_sandbox=NO
} ''}
]; '';
in in
@ -108,10 +110,7 @@ in
userlist = mkOption { userlist = mkOption {
default = []; default = [];
description = "See <option>userlistFile</option>.";
description = ''
See <option>userlistFile</option>.
'';
}; };
userlistFile = mkOption { userlistFile = mkOption {
@ -127,13 +126,20 @@ in
}; };
anonymousUserHome = mkOption { anonymousUserHome = mkOption {
type = types.path;
default = "/home/ftp/"; default = "/home/ftp/";
description = '' description = ''
Directory to consider the HOME of the anonymous user. Directory to consider the HOME of the anonymous user.
''; '';
}; };
} // (listToAttrs (catAttrs "nixosOption" optionDescription)) ; rsaCertFile = mkOption {
type = types.nullOr types.path;
default = null;
description = "RSA certificate file.";
};
} // (listToAttrs (catAttrs "nixosOption" optionDescription));
}; };
@ -142,14 +148,12 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [ assertions = singleton
{ { assertion =
assertion =
(cfg.forceLocalLoginsSSL -> cfg.rsaCertFile != null) (cfg.forceLocalLoginsSSL -> cfg.rsaCertFile != null)
&& (cfg.forceLocalDataSSL -> cfg.rsaCertFile != null); && (cfg.forceLocalDataSSL -> cfg.rsaCertFile != null);
message = "vsftpd: If forceLocalLoginsSSL or forceLocalDataSSL is true then a rsaCertFile must be provided!"; message = "vsftpd: If forceLocalLoginsSSL or forceLocalDataSSL is true then a rsaCertFile must be provided!";
} };
];
users.extraUsers = users.extraUsers =
[ { name = "vsftpd"; [ { name = "vsftpd";
@ -157,7 +161,7 @@ in
description = "VSFTPD user"; description = "VSFTPD user";
home = "/homeless-shelter"; home = "/homeless-shelter";
} }
] ++ pkgs.lib.optional cfg.anonymousUser ] ++ optional cfg.anonymousUser
{ name = "ftp"; { name = "ftp";
uid = config.ids.uids.ftp; uid = config.ids.uids.ftp;
group = "ftp"; group = "ftp";
@ -165,41 +169,27 @@ in
home = cfg.anonymousUserHome; home = cfg.anonymousUserHome;
}; };
users.extraGroups = singleton users.extraGroups.ftp.gid = config.ids.gids.ftp;
{ name = "ftp";
gid = config.ids.gids.ftp;
};
# If you really have to access root via FTP use mkOverride or userlistDeny # If you really have to access root via FTP use mkOverride or userlistDeny
# = false and whitelist root # = false and whitelist root
services.vsftpd.userlist = if cfg.userlistDeny then ["root"] else []; services.vsftpd.userlist = if cfg.userlistDeny then ["root"] else [];
environment.etc."vsftpd.conf".text = systemd.services.vsftpd =
concatMapStrings (x: "${x.cfgText}\n") optionDescription { description = "Vsftpd Server";
+ ''
${if cfg.userlistFile == null then ""
else "userlist_file=${cfg.userlistFile}"}
background=NO
listen=YES
nopriv_user=vsftpd
secure_chroot_dir=/var/empty
'';
jobs.vsftpd = wantedBy = [ "multi-user.target" ];
{ description = "vsftpd server";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart = preStart =
'' optionalString cfg.anonymousUser
${if cfg.anonymousUser then '' ''
mkdir -p -m 555 ${cfg.anonymousUserHome} mkdir -p -m 555 ${cfg.anonymousUserHome}
chown -R ftp:ftp ${cfg.anonymousUserHome} chown -R ftp:ftp ${cfg.anonymousUserHome}
'' else ""} '';
'';
exec = "${vsftpd}/sbin/vsftpd /etc/vsftpd.conf"; serviceConfig.ExecStart = "@${vsftpd}/sbin/vsftpd vsftpd ${configFile}";
serviceConfig.Restart = "always";
serviceConfig.Type = "forking";
}; };
}; };

View File

@ -149,7 +149,7 @@ in
'' ''
LogLevel info LogLevel info
SystemGroup root SystemGroup root wheel
Listen localhost:631 Listen localhost:631
Listen /var/run/cups/cups.sock Listen /var/run/cups/cups.sock

View File

@ -8,11 +8,14 @@ let
queuelen = if cfg.queuelen == null then "" else "-q ${toString cfg.queuelen}"; queuelen = if cfg.queuelen == null then "" else "-q ${toString cfg.queuelen}";
# Duplicate code, also found in cron.nix. Needs deduplication.
systemCronJobs = systemCronJobs =
'' ''
SHELL=${pkgs.bash}/bin/bash SHELL=${pkgs.bash}/bin/bash
PATH=${config.system.path}/bin:${config.system.path}/sbin PATH=${config.system.path}/bin:${config.system.path}/sbin
MAILTO="${config.services.cron.mailto}" ${optionalString (config.services.cron.mailto != null) ''
MAILTO="${config.services.cron.mailto}"
''}
NIX_CONF_DIR=/etc/nix NIX_CONF_DIR=/etc/nix
${pkgs.lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)} ${pkgs.lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)}
''; '';

View File

@ -91,7 +91,7 @@ in {
target = "elasticsearch/logging.yml"; } target = "elasticsearch/logging.yml"; }
]; ];
systemd.services.elasticsearch = mkIf cfg.enable { systemd.services.elasticsearch = {
description = "Elasticsearch daemon"; description = "Elasticsearch daemon";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network-interfaces.target" ]; after = [ "network-interfaces.target" ];

View File

@ -15,7 +15,7 @@ let
toOption = x: toOption = x:
if x == true then "true" if x == true then "true"
else if x == false then "false" else if x == false then "false"
else if builtins.isInt x then toString x else if isInt x then toString x
else toString ''\"${x}\"''; else toString ''\"${x}\"'';
# All lines in settings.json end with a ',' (comma), except for the last # All lines in settings.json end with a ',' (comma), except for the last

View File

@ -17,8 +17,8 @@ let
getPort = cfg: if cfg.port != 0 then cfg.port else if cfg.enableSSL then 443 else 80; getPort = cfg: if cfg.port != 0 then cfg.port else if cfg.enableSSL then 443 else 80;
extraModules = attrByPath ["extraModules"] [] mainCfg; extraModules = attrByPath ["extraModules"] [] mainCfg;
extraForeignModules = filter builtins.isAttrs extraModules; extraForeignModules = filter isAttrs extraModules;
extraApacheModules = filter (x: !(builtins.isAttrs x)) extraModules; # I'd prefer using builtins.isString here, but doesn't exist yet extraApacheModules = filter isString extraModules;
makeServerInfo = cfg: { makeServerInfo = cfg: {
@ -628,10 +628,10 @@ in
preStart = preStart =
'' ''
mkdir -m 0750 -p ${mainCfg.stateDir} mkdir -m 0750 -p ${mainCfg.stateDir}
chown root.${mainCfg.group} ${mainCfg.stateDir} [ $(id -u) != 0 ] || chown root.${mainCfg.group} ${mainCfg.stateDir}
${optionalString version24 '' ${optionalString version24 ''
mkdir -m 0750 -p "${mainCfg.stateDir}/runtime" mkdir -m 0750 -p "${mainCfg.stateDir}/runtime"
chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime" [ $(id -u) != 0 ] || chown root.${mainCfg.group} "${mainCfg.stateDir}/runtime"
''} ''}
mkdir -m 0700 -p ${mainCfg.logDir} mkdir -m 0700 -p ${mainCfg.logDir}
@ -659,6 +659,7 @@ in
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}"; serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}";
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop"; serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
serviceConfig.Type = "forking"; serviceConfig.Type = "forking";
serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid";
serviceConfig.Restart = "always"; serviceConfig.Restart = "always";
}; };

View File

@ -72,11 +72,11 @@ let
# Unpack Mediawiki and put the config file in its root directory. # Unpack Mediawiki and put the config file in its root directory.
mediawikiRoot = pkgs.stdenv.mkDerivation rec { mediawikiRoot = pkgs.stdenv.mkDerivation rec {
name= "mediawiki-1.20.5"; name= "mediawiki-1.20.7";
src = pkgs.fetchurl { src = pkgs.fetchurl {
url = "http://download.wikimedia.org/mediawiki/1.20/${name}.tar.gz"; url = "http://download.wikimedia.org/mediawiki/1.20/${name}.tar.gz";
sha256 = "0ix6khrilfdncjqnh41xjs0bd49i1q0rywycjaixjfpwj6vjbqbl"; sha256 = "0cdl2mq3nw1jymanlxn7pi3qbf5y5003q53kmc8dip73nvrwnfxm";
}; };
skins = config.skins; skins = config.skins;

View File

@ -4,7 +4,7 @@ with pkgs.lib;
let let
cfg = config.services.nginx; cfg = config.services.nginx;
nginx = pkgs.nginx.override { fullWebDAV = cfg.fullWebDAV; }; nginx = cfg.package;
configFile = pkgs.writeText "nginx.conf" '' configFile = pkgs.writeText "nginx.conf" ''
user ${cfg.user} ${cfg.group}; user ${cfg.user} ${cfg.group};
daemon off; daemon off;
@ -22,6 +22,13 @@ in
"; ";
}; };
package = mkOption {
default = pkgs.nginx;
description = "
Nginx package to use.
";
};
config = mkOption { config = mkOption {
default = "events {}"; default = "events {}";
description = " description = "
@ -46,10 +53,6 @@ in
description = "Group account under which nginx runs."; description = "Group account under which nginx runs.";
}; };
fullWebDAV = mkOption {
default = false;
description = "Compile in a third party module providing full WebDAV support";
};
}; };
}; };

View File

@ -17,7 +17,7 @@ in
# Note: the order in which desktop manager modules are imported here # Note: the order in which desktop manager modules are imported here
# determines the default: later modules (if enabled) are preferred. # determines the default: later modules (if enabled) are preferred.
# E.g., if KDE is enabled, it supersedes xterm. # E.g., if KDE is enabled, it supersedes xterm.
imports = [ ./none.nix ./xterm.nix ./xfce.nix ./gnome.nix ./kde4.nix ./e17.nix ]; imports = [ ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./e17.nix ];
options = { options = {

View File

@ -1,42 +0,0 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.xserver.desktopManager.gnome;
gnome = pkgs.gnome;
in
{
options = {
services.xserver.desktopManager.gnome.enable = mkOption {
default = false;
example = true;
description = "Enable a gnome terminal as a desktop manager.";
};
};
config = mkIf cfg.enable {
services.xserver.desktopManager.session = singleton
{ name = "gnome";
start = ''
${gnome.gnometerminal}/bin/gnome-terminal -ls &
waitPID=$!
'';
};
environment.systemPackages =
[ gnome.gnometerminal
gnome.GConf
gnome.gconfeditor
];
};
}

View File

@ -72,6 +72,7 @@ in
pkgs.xfce.thunar_volman pkgs.xfce.thunar_volman
pkgs.xfce.gvfs pkgs.xfce.gvfs
pkgs.xfce.xfce4_appfinder pkgs.xfce.xfce4_appfinder
pkgs.xfce.tumbler
] ]
++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager; ++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager;

View File

@ -44,7 +44,9 @@ let
# since presumably the desktop environment will handle these. # since presumably the desktop environment will handle these.
if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
export _INHIBITION_LOCK_TAKEN=1 export _INHIBITION_LOCK_TAKEN=1
exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType" if ! ${config.systemd.package}/bin/loginctl show-session $XDG_SESSION_ID | grep -q '^RemoteHost='; then
exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType"
fi
fi fi
''} ''}

View File

@ -57,6 +57,13 @@ let cfg = config.services.xserver.synaptics; in
description = "Whether to enable tap buttons."; description = "Whether to enable tap buttons.";
}; };
buttonsMap = mkOption {
default = [1 2 3];
example = [1 3 2];
description = "Remap touchpad buttons.";
apply = map toString;
};
palmDetect = mkOption { palmDetect = mkOption {
default = false; default = false;
example = true; example = true;
@ -104,10 +111,13 @@ let cfg = config.services.xserver.synaptics; in
Option "MinSpeed" "${cfg.minSpeed}" Option "MinSpeed" "${cfg.minSpeed}"
Option "MaxSpeed" "${cfg.maxSpeed}" Option "MaxSpeed" "${cfg.maxSpeed}"
Option "AccelFactor" "${cfg.accelFactor}" Option "AccelFactor" "${cfg.accelFactor}"
Option "TapButton1" "${if cfg.tapButtons then "1" else "0"}"
Option "TapButton2" "${if cfg.tapButtons then "2" else "0"}"
Option "TapButton3" "${if cfg.tapButtons then "3" else "0"}"
${if cfg.tapButtons then "" else ''Option "MaxTapTime" "0"''} ${if cfg.tapButtons then "" else ''Option "MaxTapTime" "0"''}
Option "TapButton1" "${builtins.elemAt cfg.buttonsMap 0}"
Option "TapButton2" "${builtins.elemAt cfg.buttonsMap 1}"
Option "TapButton3" "${builtins.elemAt cfg.buttonsMap 2}"
Option "ClickFinger1" "${builtins.elemAt cfg.buttonsMap 0}"
Option "ClickFinger2" "${builtins.elemAt cfg.buttonsMap 1}"
Option "ClickFinger3" "${builtins.elemAt cfg.buttonsMap 2}"
Option "VertTwoFingerScroll" "${if cfg.twoFingerScroll then "1" else "0"}" Option "VertTwoFingerScroll" "${if cfg.twoFingerScroll then "1" else "0"}"
Option "HorizTwoFingerScroll" "${if cfg.twoFingerScroll then "1" else "0"}" Option "HorizTwoFingerScroll" "${if cfg.twoFingerScroll then "1" else "0"}"
Option "VertEdgeScroll" "${if cfg.vertEdgeScroll then "1" else "0"}" Option "VertEdgeScroll" "${if cfg.vertEdgeScroll then "1" else "0"}"

View File

@ -17,18 +17,7 @@ let
#! ${pkgs.stdenv.shell} #! ${pkgs.stdenv.shell}
export XKB_BINDIR=${pkgs.xorg.xkbcomp}/bin export XKB_BINDIR=${pkgs.xorg.xkbcomp}/bin
export XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/dri export XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/dri
exec ${pkgs.xorg.xorgserver}/bin/Xvfb "$@" -xkbdir "${pkgs.xkeyboard_config}/etc/X11/xkb" exec ${pkgs.xorg.xorgserver}/bin/Xvfb "$@" -xkbdir ${pkgs.xkeyboard_config}/etc/X11/xkb
'';
# xinetd is insanely braindamaged in that it sends stderr to
# stdout. Thus requires just about any xinetd program to be
# wrapped to redirect its stderr. Sigh.
x11vncWrapper = pkgs.writeScriptBin "x11vnc-wrapper"
''
#! ${pkgs.stdenv.shell}
export PATH=${makeSearchPath "bin" [ xvfbWrapper pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash ]}:$PATH
export FD_GEOM=1024x786x24
exec ${pkgs.x11vnc}/bin/x11vnc -inetd -display WAIT:1024x786:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw -ssl SAVE 2> /var/log/x11vnc.log
''; '';
in in
@ -38,6 +27,7 @@ in
config = { config = {
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.videoDrivers = [];
# Enable KDM. Any display manager will do as long as it supports XDMCP. # Enable KDM. Any display manager will do as long as it supports XDMCP.
services.xserver.displayManager.kdm.enable = true; services.xserver.displayManager.kdm.enable = true;
@ -52,13 +42,38 @@ in
Xaccess=${pkgs.writeText "Xaccess" "localhost"} Xaccess=${pkgs.writeText "Xaccess" "localhost"}
''; '';
services.xinetd.enable = true; networking.firewall.allowedTCPPorts = [ 5900 ];
services.xinetd.services = singleton
{ name = "x11vnc"; systemd.sockets.terminal-server =
port = 5900; { description = "Terminal Server Socket";
unlisted = true; wantedBy = [ "sockets.target" ];
user = "root"; before = [ "multi-user.target" ];
server = "${x11vncWrapper}/bin/x11vnc-wrapper"; socketConfig.Accept = true;
socketConfig.ListenStream = 5900;
};
systemd.services."terminal-server@" =
{ description = "Terminal Server";
path =
[ xvfbWrapper pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth
pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash
];
environment.FD_GEOM = "1024x786x24";
environment.FD_XDMCP_IF = "127.0.0.1";
#environment.FIND_DISPLAY_OUTPUT = "/tmp/foo"; # to debug the "find display" script
serviceConfig =
{ StandardInput = "socket";
StandardOutput = "socket";
StandardError = "journal";
ExecStart = "@${pkgs.x11vnc}/bin/x11vnc x11vnc -inetd -display WAIT:1024x786:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw -ssl SAVE";
# Don't kill the X server when the user quits the VNC
# connection. FIXME: the X server should run in a
# separate systemd session.
KillMode = "process";
};
}; };
}; };

View File

@ -343,6 +343,18 @@ in
''; '';
}; };
serverFlagsSection = mkOption {
default = "";
example =
''
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
'';
description = "Contents of the ServerFlags section of the X server configuration file.";
};
moduleSection = mkOption { moduleSection = mkOption {
type = types.lines; type = types.lines;
default = ""; default = "";
@ -586,6 +598,7 @@ in
'' ''
Section "ServerFlags" Section "ServerFlags"
Option "AllowMouseOpenFail" "on" Option "AllowMouseOpenFail" "on"
${cfg.serverFlagsSection}
EndSection EndSection
Section "Module" Section "Module"

View File

@ -71,7 +71,7 @@ in
${ ${
let let
set' = mapAttrs (n: v: if builtins.isString v then noDepEntry v else v) set; set' = mapAttrs (n: v: if isString v then noDepEntry v else v) set;
withHeadlines = addAttributeName set'; withHeadlines = addAttributeName set';
in textClosureMap id (withHeadlines) (attrNames withHeadlines) in textClosureMap id (withHeadlines) (attrNames withHeadlines)
} }

View File

@ -34,16 +34,24 @@ let
in '' in ''
mkdir $out mkdir $out
if [ ! -f ${kernelPath} ]; then # Containers don't have their own kernel or initrd. They boot
echo "The bootloader cannot find the proper kernel image." # directly into stage 2.
echo "(Expecting ${kernelPath})" ${optionalString (!config.boot.isContainer) ''
false if [ ! -f ${kernelPath} ]; then
fi echo "The bootloader cannot find the proper kernel image."
echo "(Expecting ${kernelPath})"
false
fi
ln -s ${kernelPath} $out/kernel ln -s ${kernelPath} $out/kernel
ln -s ${config.system.modulesTree} $out/kernel-modules ln -s ${config.system.modulesTree} $out/kernel-modules
ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd echo -n "$kernelParams" > $out/kernel-params
ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd
ln -s ${config.hardware.firmware} $out/firmware
''}
echo "$activationScript" > $out/activate echo "$activationScript" > $out/activate
substituteInPlace $out/activate --subst-var out substituteInPlace $out/activate --subst-var out
@ -56,9 +64,7 @@ let
ln -s ${config.system.build.etc}/etc $out/etc ln -s ${config.system.build.etc}/etc $out/etc
ln -s ${config.system.path} $out/sw ln -s ${config.system.path} $out/sw
ln -s "$systemd" $out/systemd ln -s "$systemd" $out/systemd
ln -s ${config.hardware.firmware} $out/firmware
echo -n "$kernelParams" > $out/kernel-params
echo -n "$configurationName" > $out/configuration-name echo -n "$configurationName" > $out/configuration-name
echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
echo -n "$nixosVersion" > $out/nixos-version echo -n "$nixosVersion" > $out/nixos-version

View File

@ -145,7 +145,7 @@ in
###### implementation ###### implementation
config = { config = mkIf (!config.boot.isContainer) {
system.build = { inherit kernel; }; system.build = { inherit kernel; };
@ -230,9 +230,10 @@ in
{ description = "Load Kernel Modules"; { description = "Load Kernel Modules";
wantedBy = [ "sysinit.target" "multi-user.target" ]; wantedBy = [ "sysinit.target" "multi-user.target" ];
before = [ "sysinit.target" "shutdown.target" ]; before = [ "sysinit.target" "shutdown.target" ];
conflicts = [ "shutdown.target" ];
unitConfig = unitConfig =
{ DefaultDependencies = "no"; { DefaultDependencies = false;
Conflicts = "shutdown.target"; ConditionCapability = "CAP_SYS_MODULE";
}; };
serviceConfig = serviceConfig =
{ Type = "oneshot"; { Type = "oneshot";

View File

@ -44,7 +44,7 @@ in
boot.loader.grub = { boot.loader.grub = {
enable = mkOption { enable = mkOption {
default = true; default = !config.boot.isContainer;
type = types.bool; type = types.bool;
description = '' description = ''
Whether to enable the GNU GRUB boot loader. Whether to enable the GNU GRUB boot loader.

View File

@ -66,7 +66,7 @@ with pkgs.lib;
###### implementation ###### implementation
config = { config = mkIf (!config.boot.isContainer) {
environment.etc = singleton environment.etc = singleton
{ source = pkgs.writeText "modprobe.conf" { source = pkgs.writeText "modprobe.conf"

View File

@ -6,20 +6,20 @@ with pkgs.lib;
# This unit saves the value of the system clock to the hardware # This unit saves the value of the system clock to the hardware
# clock on shutdown. # clock on shutdown.
systemd.units."save-hwclock.service" = systemd.services.save-hwclock =
{ wantedBy = [ "shutdown.target" ]; { description = "Save Hardware Clock";
text = wantedBy = [ "shutdown.target" ];
''
[Unit]
Description=Save Hardware Clock
DefaultDependencies=no
Before=shutdown.target
[Service] unitConfig = {
Type=oneshot DefaultDependencies = false;
ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"} ConditionVirtualization = "!systemd-nspawn";
''; };
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.utillinux}/sbin/hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"}";
};
}; };
boot.kernel.sysctl."kernel.poweroff_cmd" = "${config.systemd.package}/sbin/poweroff"; boot.kernel.sysctl."kernel.poweroff_cmd" = "${config.systemd.package}/sbin/poweroff";

View File

@ -328,7 +328,12 @@ in
}; };
config = { config = mkIf (!config.boot.isContainer) {
assertions = singleton
{ assertion = any (fs: fs.mountPoint == "/") (attrValues config.fileSystems);
message = "The fileSystems option does not specify your root file system.";
};
system.build.bootStage1 = bootStage1; system.build.bootStage1 = bootStage1;
system.build.initialRamdisk = initialRamdisk; system.build.initialRamdisk = initialRamdisk;

View File

@ -14,6 +14,18 @@ let
in if errors == [] then true in if errors == [] then true
else builtins.trace (concatStringsSep "\n" errors) false; else builtins.trace (concatStringsSep "\n" errors) false;
unitOption = mkOptionType {
name = "systemd option";
merge = loc: defs:
let
defs' = filterOverrides defs;
defs'' = getValues defs';
in
if isList (head defs'')
then concatLists defs''
else mergeOneOption loc defs';
};
in rec { in rec {
unitOptions = { unitOptions = {
@ -37,7 +49,7 @@ in rec {
requires = mkOption { requires = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
Start the specified units when this unit is started, and stop Start the specified units when this unit is started, and stop
this unit when the specified units are stopped or fail. this unit when the specified units are stopped or fail.
@ -46,7 +58,7 @@ in rec {
wants = mkOption { wants = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
Start the specified units when this unit is started. Start the specified units when this unit is started.
''; '';
@ -54,7 +66,7 @@ in rec {
after = mkOption { after = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
If the specified units are started at the same time as If the specified units are started at the same time as
this unit, delay this unit until they have started. this unit, delay this unit until they have started.
@ -63,7 +75,7 @@ in rec {
before = mkOption { before = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
If the specified units are started at the same time as If the specified units are started at the same time as
this unit, delay them until this unit has started. this unit, delay them until this unit has started.
@ -72,7 +84,7 @@ in rec {
bindsTo = mkOption { bindsTo = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
Like requires, but in addition, if the specified units Like requires, but in addition, if the specified units
unexpectedly disappear, this unit will be stopped as well. unexpectedly disappear, this unit will be stopped as well.
@ -81,7 +93,7 @@ in rec {
partOf = mkOption { partOf = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
If the specified units are stopped or restarted, then this If the specified units are stopped or restarted, then this
unit is stopped or restarted as well. unit is stopped or restarted as well.
@ -90,7 +102,7 @@ in rec {
conflicts = mkOption { conflicts = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = '' description = ''
If the specified units are started, then this unit is stopped If the specified units are started, then this unit is stopped
and vice versa. and vice versa.
@ -99,20 +111,20 @@ in rec {
requiredBy = mkOption { requiredBy = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = "Units that require (i.e. depend on and need to go down with) this unit."; description = "Units that require (i.e. depend on and need to go down with) this unit.";
}; };
wantedBy = mkOption { wantedBy = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
description = "Units that want (i.e. depend on) this unit."; description = "Units that want (i.e. depend on) this unit.";
}; };
unitConfig = mkOption { unitConfig = mkOption {
default = {}; default = {};
example = { RequiresMountsFor = "/data"; }; example = { RequiresMountsFor = "/data"; };
type = types.attrs; type = types.attrsOf unitOption;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Unit]</literal> section of the unit. See <literal>[Unit]</literal> section of the unit. See
@ -137,7 +149,7 @@ in rec {
environment = mkOption { environment = mkOption {
default = {}; default = {};
type = types.attrs; type = types.attrs; # FIXME
example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; }; example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
description = "Environment variables passed to the service's processes."; description = "Environment variables passed to the service's processes.";
}; };
@ -159,7 +171,7 @@ in rec {
{ StartLimitInterval = 10; { StartLimitInterval = 10;
RestartSec = 5; RestartSec = 5;
}; };
type = types.addCheck types.attrs checkService; type = types.addCheck (types.attrsOf unitOption) checkService;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Service]</literal> section of the unit. See <literal>[Service]</literal> section of the unit. See
@ -169,7 +181,7 @@ in rec {
}; };
script = mkOption { script = mkOption {
type = types.str; type = types.lines;
default = ""; default = "";
description = "Shell commands executed as the service's main process."; description = "Shell commands executed as the service's main process.";
}; };
@ -181,7 +193,7 @@ in rec {
}; };
preStart = mkOption { preStart = mkOption {
type = types.string; type = types.lines;
default = ""; default = "";
description = '' description = ''
Shell commands executed before the service's main process Shell commands executed before the service's main process
@ -190,7 +202,7 @@ in rec {
}; };
postStart = mkOption { postStart = mkOption {
type = types.string; type = types.lines;
default = ""; default = "";
description = '' description = ''
Shell commands executed after the service's main process Shell commands executed after the service's main process
@ -198,8 +210,16 @@ in rec {
''; '';
}; };
preStop = mkOption {
type = types.lines;
default = "";
description = ''
Shell commands executed to stop the service.
'';
};
postStop = mkOption { postStop = mkOption {
type = types.string; type = types.lines;
default = ""; default = "";
description = '' description = ''
Shell commands executed after the service's main process Shell commands executed after the service's main process
@ -252,7 +272,7 @@ in rec {
listenStreams = mkOption { listenStreams = mkOption {
default = []; default = [];
type = types.listOf types.string; type = types.listOf types.str;
example = [ "0.0.0.0:993" "/run/my-socket" ]; example = [ "0.0.0.0:993" "/run/my-socket" ];
description = '' description = ''
For each item in this list, a <literal>ListenStream</literal> For each item in this list, a <literal>ListenStream</literal>
@ -263,7 +283,7 @@ in rec {
socketConfig = mkOption { socketConfig = mkOption {
default = {}; default = {};
example = { ListenStream = "/run/my-socket"; }; example = { ListenStream = "/run/my-socket"; };
type = types.attrs; type = types.attrsOf unitOption;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Socket]</literal> section of the unit. See <literal>[Socket]</literal> section of the unit. See
@ -280,7 +300,7 @@ in rec {
timerConfig = mkOption { timerConfig = mkOption {
default = {}; default = {};
example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; }; example = { OnCalendar = "Sun 14:00:00"; Unit = "foo.service"; };
type = types.attrs; type = types.attrsOf unitOption;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Timer]</literal> section of the unit. See <literal>[Timer]</literal> section of the unit. See
@ -328,7 +348,7 @@ in rec {
mountConfig = mkOption { mountConfig = mkOption {
default = {}; default = {};
example = { DirectoryMode = "0775"; }; example = { DirectoryMode = "0775"; };
type = types.attrs; type = types.attrsOf unitOption;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Mount]</literal> section of the unit. See <literal>[Mount]</literal> section of the unit. See
@ -352,7 +372,7 @@ in rec {
automountConfig = mkOption { automountConfig = mkOption {
default = {}; default = {};
example = { DirectoryMode = "0775"; }; example = { DirectoryMode = "0775"; };
type = types.attrs; type = types.attrsOf unitOption;
description = '' description = ''
Each attribute in this set specifies an option in the Each attribute in this set specifies an option in the
<literal>[Automount]</literal> section of the unit. See <literal>[Automount]</literal> section of the unit. See

View File

@ -160,16 +160,48 @@ let
}; };
serviceConfig = { name, config, ... }: { serviceConfig = { name, config, ... }: {
config = { config = mkMerge
# Default path for systemd services. Should be quite minimal. [ { # Default path for systemd services. Should be quite minimal.
path = path =
[ pkgs.coreutils [ pkgs.coreutils
pkgs.findutils pkgs.findutils
pkgs.gnugrep pkgs.gnugrep
pkgs.gnused pkgs.gnused
systemd systemd
]; ];
}; environment.PATH = config.path;
}
(mkIf (config.preStart != "")
{ serviceConfig.ExecStartPre = makeJobScript "${name}-pre-start" ''
#! ${pkgs.stdenv.shell} -e
${config.preStart}
'';
})
(mkIf (config.script != "")
{ serviceConfig.ExecStart = makeJobScript "${name}-start" ''
#! ${pkgs.stdenv.shell} -e
${config.script}
'' + " " + config.scriptArgs;
})
(mkIf (config.postStart != "")
{ serviceConfig.ExecStartPost = makeJobScript "${name}-post-start" ''
#! ${pkgs.stdenv.shell} -e
${config.postStart}
'';
})
(mkIf (config.preStop != "")
{ serviceConfig.ExecStop = makeJobScript "${name}-pre-stop" ''
#! ${pkgs.stdenv.shell} -e
${config.preStop}
'';
})
(mkIf (config.postStop != "")
{ serviceConfig.ExecStopPost = makeJobScript "${name}-post-stop" ''
#! ${pkgs.stdenv.shell} -e
${config.postStop}
'';
})
];
}; };
mountConfig = { name, config, ... }: { mountConfig = { name, config, ... }: {
@ -223,41 +255,10 @@ let
${attrsToSection def.unitConfig} ${attrsToSection def.unitConfig}
[Service] [Service]
Environment=PATH=${def.path}
Environment=LD_LIBRARY_PATH=
${let env = cfg.globalEnvironment // def.environment; ${let env = cfg.globalEnvironment // def.environment;
in concatMapStrings (n: "Environment=\"${n}=${getAttr n env}\"\n") (attrNames env)} in concatMapStrings (n: "Environment=\"${n}=${getAttr n env}\"\n") (attrNames env)}
${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"} ${optionalString (!def.restartIfChanged) "X-RestartIfChanged=false"}
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"} ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
${optionalString (def.preStart != "") ''
ExecStartPre=${makeJobScript "${name}-pre-start" ''
#! ${pkgs.stdenv.shell} -e
${def.preStart}
''}
''}
${optionalString (def.script != "") ''
ExecStart=${makeJobScript "${name}-start" ''
#! ${pkgs.stdenv.shell} -e
${def.script}
''} ${def.scriptArgs}
''}
${optionalString (def.postStart != "") ''
ExecStartPost=${makeJobScript "${name}-post-start" ''
#! ${pkgs.stdenv.shell} -e
${def.postStart}
''}
''}
${optionalString (def.postStop != "") ''
ExecStopPost=${makeJobScript "${name}-post-stop" ''
#! ${pkgs.stdenv.shell} -e
${def.postStop}
''}
''}
${attrsToSection def.serviceConfig} ${attrsToSection def.serviceConfig}
''; '';
}; };
@ -311,8 +312,6 @@ let
''; '';
}; };
nixosUnits = mapAttrsToList makeUnit cfg.units;
units = pkgs.runCommand "units" { preferLocalBuild = true; } units = pkgs.runCommand "units" { preferLocalBuild = true; }
'' ''
mkdir -p $out mkdir -p $out
@ -338,7 +337,7 @@ let
done done
done done
for i in ${toString nixosUnits}; do for i in ${toString (mapAttrsToList (n: v: v.unit) cfg.units)}; do
ln -s $i/* $out/ ln -s $i/* $out/
done done
@ -348,14 +347,14 @@ let
${concatStrings (mapAttrsToList (name: unit: ${concatStrings (mapAttrsToList (name: unit:
concatMapStrings (name2: '' concatMapStrings (name2: ''
mkdir -p $out/${name2}.wants mkdir -p $out/'${name2}.wants'
ln -sfn ../${name} $out/${name2}.wants/ ln -sfn '../${name}' $out/'${name2}.wants'/
'') unit.wantedBy) cfg.units)} '') unit.wantedBy) cfg.units)}
${concatStrings (mapAttrsToList (name: unit: ${concatStrings (mapAttrsToList (name: unit:
concatMapStrings (name2: '' concatMapStrings (name2: ''
mkdir -p $out/${name2}.requires mkdir -p $out/'${name2}.requires'
ln -sfn ../${name} $out/${name2}.requires/ ln -sfn '../${name}' $out/'${name2}.requires'/
'') unit.requiredBy) cfg.units)} '') unit.requiredBy) cfg.units)}
ln -s ${cfg.defaultUnit} $out/default.target ln -s ${cfg.defaultUnit} $out/default.target
@ -387,32 +386,41 @@ in
description = "Definition of systemd units."; description = "Definition of systemd units.";
default = {}; default = {};
type = types.attrsOf types.optionSet; type = types.attrsOf types.optionSet;
options = { options = { name, config, ... }:
text = mkOption { { options = {
type = types.str; text = mkOption {
description = "Text of this systemd unit."; type = types.str;
description = "Text of this systemd unit.";
};
enable = mkOption {
default = true;
type = types.bool;
description = ''
If set to false, this unit will be a symlink to
/dev/null. This is primarily useful to prevent specific
template instances (e.g. <literal>serial-getty@ttyS0</literal>)
from being started.
'';
};
requiredBy = mkOption {
default = [];
type = types.listOf types.string;
description = "Units that require (i.e. depend on and need to go down with) this unit.";
};
wantedBy = mkOption {
default = [];
type = types.listOf types.string;
description = "Units that want (i.e. depend on) this unit.";
};
unit = mkOption {
internal = true;
description = "The generated unit.";
};
};
config = {
unit = makeUnit name config;
};
}; };
enable = mkOption {
default = true;
type = types.bool;
description = ''
If set to false, this unit will be a symlink to
/dev/null. This is primarily useful to prevent specific
template instances (e.g. <literal>serial-getty@ttyS0</literal>)
from being started.
'';
};
requiredBy = mkOption {
default = [];
type = types.listOf types.string;
description = "Units that require (i.e. depend on and need to go down with) this unit.";
};
wantedBy = mkOption {
default = [];
type = types.listOf types.string;
description = "Units that want (i.e. depend on) this unit.";
};
};
}; };
systemd.packages = mkOption { systemd.packages = mkOption {
@ -486,6 +494,16 @@ in
''; '';
}; };
systemd.extraConfig = mkOption {
default = "";
type = types.lines;
example = "DefaultLimitCORE=infinity";
description = ''
Extra config options for systemd. See man systemd-system.conf for
available options.
'';
};
services.journald.console = mkOption { services.journald.console = mkOption {
default = ""; default = "";
type = types.str; type = types.str;
@ -516,9 +534,19 @@ in
''; '';
}; };
services.journald.extraConfig = mkOption {
default = "";
type = types.lines;
example = "Storage=volatile";
description = ''
Extra config options for systemd-journald. See man journald.conf
for available options.
'';
};
services.logind.extraConfig = mkOption { services.logind.extraConfig = mkOption {
default = ""; default = "";
type = types.str; type = types.lines;
example = "HandleLidSwitch=ignore"; example = "HandleLidSwitch=ignore";
description = '' description = ''
Extra config options for systemd-logind. See man logind.conf for Extra config options for systemd-logind. See man logind.conf for
@ -555,6 +583,7 @@ in
environment.etc."systemd/system.conf".text = environment.etc."systemd/system.conf".text =
'' ''
[Manager] [Manager]
${config.systemd.extraConfig}
''; '';
environment.etc."systemd/journald.conf".text = environment.etc."systemd/journald.conf".text =
@ -566,6 +595,7 @@ in
ForwardToConsole=yes ForwardToConsole=yes
TTYPath=${config.services.journald.console} TTYPath=${config.services.journald.console}
''} ''}
${config.services.journald.extraConfig}
''; '';
environment.etc."systemd/logind.conf".text = environment.etc."systemd/logind.conf".text =
@ -585,13 +615,6 @@ in
mkdir -p /var/log/journal mkdir -p /var/log/journal
chmod 0755 /var/log/journal chmod 0755 /var/log/journal
# Regenerate the hardware database /var/lib/udev/hwdb.bin
# whenever systemd changes.
if [ ! -e /var/lib/udev/prev-systemd -o "$(readlink /var/lib/udev/prev-systemd)" != ${systemd} ]; then
echo "regenerating udev hardware database..."
${systemd}/bin/udevadm hwdb --update && ln -sfn ${systemd} /var/lib/udev/prev-systemd
fi
# Make all journals readable to users in the wheel and adm # Make all journals readable to users in the wheel and adm
# groups, in addition to those in the systemd-journal group. # groups, in addition to those in the systemd-journal group.
# Users can always read their own journals. # Users can always read their own journals.

View File

@ -33,6 +33,8 @@ with pkgs.lib;
after = [ "systemd-modules-load.service" ]; after = [ "systemd-modules-load.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
unitConfig.ConditionPathIsReadWrite = "/sys/devices/";
path = [ pkgs.cpufrequtils ]; path = [ pkgs.cpufrequtils ];
preStart = '' preStart = ''

View File

@ -81,6 +81,7 @@ in
options = { options = {
fileSystems = mkOption { fileSystems = mkOption {
default = {};
example = { example = {
"/".device = "/dev/hda1"; "/".device = "/dev/hda1";
"/data" = { "/data" = {

View File

@ -76,7 +76,7 @@ in
}; };
systemd.services."zfs-mount" = { systemd.services."zfs-mount" = {
description = "Mount zfs volumes"; description = "Mount ZFS Volumes";
after = [ "zpool-import.service" ]; after = [ "zpool-import.service" ];
wantedBy = [ "local-fs.target" ]; wantedBy = [ "local-fs.target" ];
serviceConfig = { serviceConfig = {

View File

@ -55,9 +55,9 @@ in
{ description = "Setup Virtual Console"; { description = "Setup Virtual Console";
wantedBy = [ "sysinit.target" "multi-user.target" ]; wantedBy = [ "sysinit.target" "multi-user.target" ];
before = [ "sysinit.target" "shutdown.target" ]; before = [ "sysinit.target" "shutdown.target" ];
conflicts = [ "shutdown.target" ];
unitConfig = unitConfig =
{ DefaultDependencies = "no"; { DefaultDependencies = "no";
Conflicts = "shutdown.target";
ConditionPathExists = "/dev/tty1"; ConditionPathExists = "/dev/tty1";
}; };
serviceConfig = serviceConfig =

View File

@ -270,6 +270,8 @@ in
before = [ "network.target" ]; before = [ "network.target" ];
wantedBy = [ "network.target" ]; wantedBy = [ "network.target" ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
path = [ pkgs.iproute ]; path = [ pkgs.iproute ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";

View File

@ -31,6 +31,8 @@ with pkgs.lib;
task = true; task = true;
unitConfig.ConditionPathIsReadWrite = "/sys/class/scsi_host";
script = '' script = ''
shopt -s nullglob shopt -s nullglob
for x in /sys/class/scsi_host/host*/link_power_management_policy; do for x in /sys/class/scsi_host/host*/link_power_management_policy; do

View File

@ -0,0 +1,114 @@
{ config, pkgs, ... }:
with pkgs.lib;
let
makeScript = name: service: pkgs.writeScript "${name}-runner"
''
#! ${pkgs.perl}/bin/perl -w -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl
use File::Slurp;
sub run {
my ($cmd) = @_;
my @args = split " ", $cmd;
my $prog;
if (substr($args[0], 0, 1) eq "@") {
$prog = substr($args[0], 1);
shift @args;
} else {
$prog = $args[0];
}
my $pid = fork;
if ($pid == 0) {
setpgrp; # don't receive SIGINT etc. from terminal
exec { $prog } @args;
die "failed to exec $prog\n";
} elsif (!defined $pid) {
die "failed to fork: $!\n";
}
return $pid;
};
sub run_wait {
my ($cmd) = @_;
my $pid = run $cmd;
die if waitpid($pid, 0) != $pid;
return $?;
};
# Set the environment. FIXME: escaping.
foreach my $key (keys %ENV) {
next if $key eq 'LOCALE_ARCHIVE';
delete $ENV{$key};
}
${concatStrings (mapAttrsToList (n: v: ''
$ENV{'${n}'} = '${v}';
'') service.environment)}
# Run the ExecStartPre program. FIXME: this could be a list.
my $preStart = '${service.serviceConfig.ExecStartPre or ""}';
if ($preStart ne "") {
print STDERR "running ExecStartPre: $preStart\n";
my $res = run_wait $preStart;
die "$0: ExecStartPre failed with status $res\n" if $res;
};
# Run the ExecStart program.
my $cmd = '${service.serviceConfig.ExecStart}';
print STDERR "running ExecStart: $cmd\n";
my $mainPid = run $cmd;
$ENV{'MAINPID'} = $mainPid;
# Catch SIGINT, propagate to the main program.
sub intHandler {
print STDERR "got SIGINT, stopping service...\n";
kill 'INT', $mainPid;
};
$SIG{'INT'} = \&intHandler;
$SIG{'QUIT'} = \&intHandler;
# Run the ExecStartPost program.
my $postStart = '${service.serviceConfig.ExecStartPost or ""}';
if ($postStart ne "") {
print STDERR "running ExecStartPost: $postStart\n";
my $res = run_wait $postStart;
die "$0: ExecStartPost failed with status $res\n" if $res;
}
# Wait for the main program to exit.
die if waitpid($mainPid, 0) != $mainPid;
my $mainRes = $?;
# Run the ExecStopPost program.
my $postStop = '${service.serviceConfig.ExecStopPost or ""}';
if ($postStop ne "") {
print STDERR "running ExecStopPost: $postStop\n";
my $res = run_wait $postStop;
die "$0: ExecStopPost failed with status $res\n" if $res;
}
exit($mainRes & 127 ? 255 : $mainRes << 8);
'';
in
{
options = {
systemd.services = mkOption {
options =
{ config, name, ... }:
{ options.runner = mkOption {
internal = true;
description = ''
A script that runs the service outside of systemd,
useful for testing or for using NixOS services outside
of NixOS.
'';
};
config.runner = makeScript name config;
};
};
};
}

View File

@ -160,4 +160,9 @@ with pkgs.lib;
environment.systemPackages = [ pkgs.cryptsetup ]; environment.systemPackages = [ pkgs.cryptsetup ];
boot.initrd.supportedFilesystems = [ "unionfs-fuse" ]; boot.initrd.supportedFilesystems = [ "unionfs-fuse" ];
# Prevent logging in as root without a password. This doesn't really matter,
# since the only PAM services that allow logging in with a null
# password are local ones that are inaccessible on EC2 machines.
security.initialRootPassword = "!";
} }

View File

@ -0,0 +1,137 @@
{ config, pkgs, ... }:
with pkgs.lib;
{
options = {
boot.isContainer = mkOption {
type = types.bool;
default = false;
description = ''
Whether this NixOS machine is a lightweight container running
in another NixOS system.
'';
};
systemd.containers = mkOption {
type = types.attrsOf (types.submodule (
{ config, options, name, ... }:
{
options = {
root = mkOption {
type = types.path;
description = ''
The root directory of the container.
'';
};
config = mkOption {
description = ''
A specification of the desired configuration of this
container, as a NixOS module.
'';
};
path = mkOption {
type = types.path;
example = "/nix/var/nix/profiles/containers/webserver";
description = ''
As an alternative to specifying
<option>config</option>, you can specify the path to
the evaluated NixOS system configuration, typically a
symlink to a system profile.
'';
};
};
config = mkMerge
[ { root = mkDefault "/var/lib/containers/${name}";
}
(mkIf options.config.isDefined {
path = (import ../../lib/eval-config.nix {
modules =
let extraConfig =
{ boot.isContainer = true;
security.initialRootPassword = "!";
networking.hostName = mkDefault name;
};
in [ extraConfig config.config ];
prefix = [ "systemd" "containers" name ];
}).config.system.build.toplevel;
})
];
}));
default = {};
example = literalExample
''
{ webserver =
{ root = "/containers/webserver";
path = "/nix/var/nix/profiles/webserver";
};
database =
{ root = "/containers/database";
config =
{ config, pkgs, ... }:
{ services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql92;
};
};
}
'';
description = ''
A set of NixOS system configurations to be run as lightweight
containers. Each container appears as a service
<literal>container-<replaceable>name</replaceable></literal>
on the host system, allowing it to be started and stopped via
<command>systemctl</command> .
'';
};
};
config = {
systemd.services = mapAttrs' (name: container: nameValuePair "container-${name}"
{ description = "Container '${name}'";
wantedBy = [ "multi-user.target" ];
unitConfig.RequiresMountsFor = [ container.root ];
preStart =
''
mkdir -p -m 0755 ${container.root}/etc
if ! [ -e ${container.root}/etc/os-release ]; then
touch ${container.root}/etc/os-release
fi
'';
serviceConfig.ExecStart =
"${config.systemd.package}/bin/systemd-nspawn -M ${name} -D ${container.root} --bind-ro=/nix ${container.path}/init";
preStop =
''
pid="$(cat /sys/fs/cgroup/systemd/machine/${name}.nspawn/system/tasks 2> /dev/null)"
if [ -n "$pid" ]; then
# Send the RTMIN+3 signal, which causes the container
# systemd to start halt.target.
echo "killing container systemd, PID = $pid"
kill -RTMIN+3 $pid
# Wait for the container to exit. We can't let systemd
# do this because it will send a signal to the entire
# cgroup.
for ((n = 0; n < 180; n++)); do
if ! kill -0 $pid 2> /dev/null; then break; fi
sleep 1
done
fi
'';
}) config.systemd.containers;
};
}

View File

@ -82,8 +82,11 @@ in
mkdir -p /var/log/libvirt/qemu -m 755 mkdir -p /var/log/libvirt/qemu -m 755
rm -f /var/run/libvirtd.pid rm -f /var/run/libvirtd.pid
mkdir -p /var/lib/libvirt -m 700 mkdir -p /var/lib/libvirt
mkdir -p /var/lib/libvirt/dnsmasq -m 700 mkdir -p /var/lib/libvirt/dnsmasq
chmod 755 /var/lib/libvirt
chmod 755 /var/lib/libvirt/dnsmasq
# Libvirt unfortunately writes mutable state (such as # Libvirt unfortunately writes mutable state (such as
# runtime changes to VM, network or filter configurations) # runtime changes to VM, network or filter configurations)
@ -98,6 +101,19 @@ in
mkdir -p /etc/$(dirname $i) -m 755 mkdir -p /etc/$(dirname $i) -m 755
cp -fpd ${pkgs.libvirt}/etc/$i /etc/$i cp -fpd ${pkgs.libvirt}/etc/$i /etc/$i
done done
# libvirtd puts the full path of the emulator binary in the machine
# config file. But this path can unfortunately be garbage collected
# while still being used by the virtual machine. So update the
# emulator path on each startup to something valid (re-scan $PATH).
for file in /etc/libvirt/qemu/*.xml; do
# get (old) emulator path from config file
emulator=$(grep "^[[:space:]]*<emulator>" "$file" | sed 's,^[[:space:]]*<emulator>\(.*\)</emulator>.*,\1,')
# get a (definitely) working emulator path by re-scanning $PATH
new_emulator=$(command -v $(basename "$emulator"))
# write back
sed -i "s,^[[:space:]]*<emulator>.*, <emulator>$new_emulator</emulator> <!-- WARNING: emulator dirname is auto-updated by the nixos libvirtd module -->," "$file"
done
''; # */ ''; # */
serviceConfig.ExecStart = ''@${pkgs.libvirt}/sbin/libvirtd libvirtd --config "${configFile}" --daemon --verbose''; serviceConfig.ExecStart = ''@${pkgs.libvirt}/sbin/libvirtd libvirtd --config "${configFile}" --daemon --verbose'';

View File

@ -113,7 +113,7 @@ in
jobs.nova_objectstore = jobs.nova_objectstore =
{ name = "nova-objectstore"; { name = "nova-objectstore";
description = "Nova simple object store service"; description = "Nova Simple Object Store Service";
startOn = "ip-up"; startOn = "ip-up";
@ -129,7 +129,7 @@ in
jobs.nova_scheduler = jobs.nova_scheduler =
{ name = "nova-scheduler"; { name = "nova-scheduler";
description = "Nova scheduler service"; description = "Nova Scheduler Service";
startOn = "ip-up"; startOn = "ip-up";
@ -140,7 +140,7 @@ in
jobs.nova_compute = jobs.nova_compute =
{ name = "nova-compute"; { name = "nova-compute";
description = "Nova compute service"; description = "Nova Compute Service";
startOn = "ip-up"; startOn = "ip-up";
@ -157,7 +157,7 @@ in
jobs.nova_network = jobs.nova_network =
{ name = "nova-network"; { name = "nova-network";
description = "Nova network service"; description = "Nova Network Service";
startOn = "ip-up"; startOn = "ip-up";

View File

@ -107,4 +107,9 @@ with pkgs.lib;
boot.loader.grub.device = "/dev/sda"; boot.loader.grub.device = "/dev/sda";
services.virtualbox.enable = true; services.virtualbox.enable = true;
# Prevent logging in as root without a password. For NixOps, we
# don't need this because the user can login via SSH, and for the
# demo images, there is a demo user account that can sudo to root.
security.initialRootPassword = "!";
} }

View File

@ -107,7 +107,7 @@ in
''; '';
jobs.xend = jobs.xend =
{ description = "Xen control daemon"; { description = "Xen Control Daemon";
startOn = "stopped udevtrigger"; startOn = "stopped udevtrigger";

View File

@ -123,11 +123,13 @@ in rec {
inherit system; inherit system;
}); });
/*
iso_minimal_new_kernel = forAllSystems (system: makeIso { iso_minimal_new_kernel = forAllSystems (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;
}); });
*/
iso_graphical = forAllSystems (system: makeIso { iso_graphical = forAllSystems (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-graphical.nix; module = ./modules/installer/cd-dvd/installation-cd-graphical.nix;
@ -137,20 +139,13 @@ 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_new_kernel = forAllSystems (system: makeIso { iso_new_kernel = forAllSystems (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-new-kernel.nix; module = ./modules/installer/cd-dvd/installation-cd-new-kernel.nix;
type = "new-kernel"; type = "new-kernel";
inherit system; inherit system;
}); });
*/
# A variant with efi booting support. Once cd-minimal has a newer kernel,
# this should be enabled by default.
iso_efi = forAllSystems (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-efi.nix;
type = "efi";
maintainers = [ "shlevy" ];
inherit system;
});
# 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).

View File

@ -16,6 +16,7 @@ with import ../lib/testing.nix { inherit system minimal; };
kde4 = makeTest (import ./kde4.nix); kde4 = makeTest (import ./kde4.nix);
#kexec = makeTest (import ./kexec.nix); #kexec = makeTest (import ./kexec.nix);
login = makeTest (import ./login.nix {}); login = makeTest (import ./login.nix {});
logstash = makeTest (import ./logstash.nix);
latestKernel.login = makeTest (import ./login.nix ({ config, pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; })); latestKernel.login = makeTest (import ./login.nix ({ config, pkgs, ... }: { boot.kernelPackages = pkgs.linuxPackages_latest; }));
misc = makeTest (import ./misc.nix); misc = makeTest (import ./misc.nix);
#mpich = makeTest (import ./mpich.nix); #mpich = makeTest (import ./mpich.nix);

View File

@ -12,7 +12,7 @@ let
(import ../lib/eval-config.nix { (import ../lib/eval-config.nix {
inherit system; inherit system;
modules = modules =
[ ../modules/installer/cd-dvd/installation-cd-efi.nix [ ../modules/installer/cd-dvd/installation-cd-minimal.nix
../modules/testing/test-instrumentation.nix ../modules/testing/test-instrumentation.nix
{ key = "serial"; { key = "serial";
@ -38,7 +38,6 @@ let
config = builtins.toFile "configuration.nix" '' config = builtins.toFile "configuration.nix" ''
{ pkgs, ... }: { { pkgs, ... }: {
imports = [ ./hardware-configuration.nix <nixos/modules/testing/test-instrumentation.nix> ]; imports = [ ./hardware-configuration.nix <nixos/modules/testing/test-instrumentation.nix> ];
boot.kernelPackages = pkgs.linuxPackages_3_10;
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
boot.loader.gummiboot.enable = true; boot.loader.gummiboot.enable = true;

40
nixos/tests/logstash.nix Normal file
View File

@ -0,0 +1,40 @@
{ pkgs, ... }:
# This test runs logstash and checks if messages flows and elasticsearch is
# started
{
nodes = {
one =
{ config, pkgs, ... }:
{
services = {
logstash = {
enable = true;
inputConfig = ''
exec { command => "echo flowers" interval => 1 type => "test" }
exec { command => "echo dragons" interval => 1 type => "test" }
'';
filterConfig = ''
if [type] == "test" {
grep { match => ["message", "flowers"] drop => true }
}
'';
outputConfig = ''
stdout { codec => rubydebug }
elasticsearch { embedded => true }
'';
};
};
};
};
testScript = ''
startAll;
$one->waitForUnit("logstash.service");
$one->waitUntilSucceeds("journalctl -n 20 _SYSTEMD_UNIT=logstash.service | grep flowers");
$one->fail("journalctl -n 20 _SYSTEMD_UNIT=logstash.service | grep dragons");
$one->waitUntilSucceeds("curl -s http://127.0.0.1:9200/_status?pretty=true | grep logstash");
'';
}

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