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>
</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>

View file

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

View file

@ -21,8 +21,6 @@ let
in
{ inherit trivial lists strings stringsWithDeps attrsets sources options
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
# commonly used functions.

View file

@ -1,14 +1,16 @@
# General list operations.
let
inherit (import ./trivial.nix) deepSeq;
with import ./trivial.nix;
let
inc = builtins.add 1;
dec = n: builtins.sub n 1;
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
@ -55,10 +57,6 @@ in rec {
else [ (f (inc n) (elemAt list n)) ] ++ imap' (inc n);
in imap' 0;
# Concatenate a list of lists.
concatLists = builtins.concatLists or (fold (x: y: x ++ y) []);
# Map and concatenate the result.
concatMap = f: list: concatLists (map f list);
@ -72,24 +70,10 @@ in rec {
then fold (x: y: (flatten x) ++ y) [] 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 = 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
# predicate, returns `default' if no such element exists, or
@ -106,7 +90,7 @@ in rec {
findFirst = pred: default: list:
let found = filter pred list;
in if found == [] then default else head found;
# Return true iff function `pred' returns true for at least element
# of `list'.
@ -136,16 +120,16 @@ in rec {
# If argument is a list, return it; else, wrap it in a singleton
# list. If you're using this, you should almost certainly
# 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'.
range = first: last:
if builtins.lessThan last first
if lessThan last first
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
# `wrong', depending on the evaluation of a predicate.
partition = pred:
@ -160,7 +144,7 @@ in rec {
let
len1 = length fst;
len2 = length snd;
len = if builtins.lessThan len1 len2 then len1 else len2;
len = if lessThan len1 len2 then len1 else len2;
zipListsWith' = n:
if n != len then
[ (f (elemAt fst n) (elemAt snd n)) ]
@ -207,7 +191,7 @@ in rec {
[ (elemAt list n) ] ++ take' (inc n);
in take' 0;
# Remove the first (at most) N elements of a list.
drop = count: list:
let
@ -219,7 +203,8 @@ in rec {
drop' (dec n) ++ [ (elemAt list n) ];
in drop' (dec len);
# Return the last element of a list.
last = list:
assert list != []; elemAt list (dec (length list));
@ -237,5 +222,7 @@ in rec {
else [];
in zipTwoLists' 0;
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>";
thammers = "Tobias Hammerschmidt <jawr@gmx.de>";
the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>";
tomberek = "Thomas Bereknyei <tomberek@gmail.com>";
urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>";
vcunat = "Vladimír Čunát <vcunat@gmail.com>";
viric = "Lluís Batlle i Rossell <viric@viric.name>";
@ -63,4 +64,6 @@
winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>";
z77z = "Marco Maggesi <maggesi@math.unifi.it>";
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:
let
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)
else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args));
@ -74,7 +74,7 @@ rec {
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
declarations in all modules, combining them into a single set.
@ -260,7 +260,7 @@ rec {
options' = opt.options or
(throw "Option `${showOption loc'}' has type optionSet but has no option attribute.");
coerce = x:
if builtins.isFunction x then x
if isFunction x then x
else { config, ... }: { options = x; };
options = map coerce (flatten options');
f = tp:

View file

@ -34,12 +34,12 @@ rec {
mergeDefaultOption = loc: defs:
let list = getValues defs; in
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 isAttrs list then fold lib.mergeAttrs {} list
else if all builtins.isBool list then fold lib.or false list
else if all builtins.isString list then lib.concatStrings list
else if all builtins.isInt list && all (x: x == head list) list then head list
else if all isBool list then fold lib.or false list
else if all isString list then lib.concatStrings 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)}.";
/* Obsolete, will remove soon. Specify an option type or apply
@ -54,7 +54,7 @@ rec {
mergeListOption = mergeTypedOption "list" isList concatLists;
mergeStringOption = mergeTypedOption "string" builtins.isString lib.concatStrings;
mergeStringOption = mergeTypedOption "string" isString lib.concatStrings;
mergeOneOption = loc: defs:
if defs == [] then abort "This case should never happen."

View file

@ -2,9 +2,9 @@ let lists = import ./lists.nix; in
rec {
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"];
freebsd = ["i686-freebsd" "x86_64-freebsd" "powerpc-freebsd"];
freebsd = ["i686-freebsd" "x86_64-freebsd"];
openbsd = ["i686-openbsd" "x86_64-openbsd"];
netbsd = ["i686-netbsd" "x86_64-netbsd"];
cygwin = ["i686-cygwin"];

View file

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

View file

@ -16,7 +16,7 @@ rec {
or = x: y: x || y;
and = x: y: x && y;
mergeAttrs = x: y: x // y;
# Take a function and evaluate it with its own returned value.
fix = f: let result = f result; in result;
@ -26,7 +26,7 @@ rec {
# `seq x y' evaluates x, then returns y. That is, it forces strict
# evaluation of its first argument.
seq = x: y: if x == null then y else y;
# Like `seq', but recurses into lists and attribute sets to force evaluation
# of all list elements/attributes.
deepSeq = x: y:
@ -35,4 +35,10 @@ rec {
else if builtins.isAttrs x
then deepSeqAttrs 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 {
name = "boolean";
check = builtins.isBool;
check = isBool;
merge = loc: fold (x: y: x.value || y) false;
};
int = mkOptionType {
name = "integer";
check = builtins.isInt;
check = isInt;
merge = mergeOneOption;
};
str = mkOptionType {
name = "string";
check = builtins.isString;
check = isString;
merge = mergeOneOption;
};
@ -68,7 +68,7 @@ rec {
# separator between the values).
separatedString = sep: mkOptionType {
name = "string";
check = builtins.isString;
check = isString;
merge = loc: defs: concatStringsSep sep (getValues defs);
};
@ -170,7 +170,7 @@ rec {
functionTo = elemType: mkOptionType {
name = "function that evaluates to a(n) ${elemType.name}";
check = builtins.isFunction;
check = isFunction;
merge = loc: defs:
fnArgs: elemType.merge loc (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs);
getSubOptions = elemType.getSubOptions;
@ -183,10 +183,10 @@ rec {
in
mkOptionType rec {
name = "submodule";
check = x: isAttrs x || builtins.isFunction x;
check = x: isAttrs x || isFunction x;
merge = loc: defs:
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;
in (evalModules { inherit modules; args.name = last loc; prefix = loc; }).config;
getSubOptions = prefix: (evalModules

View file

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

View file

@ -652,6 +652,37 @@ $ qemu-system-x86_64 -kernel ./kernel/bzImage -initrd ./initrd/initrd -hda /dev/
</listitem>
</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>
</para>

View file

@ -369,9 +369,23 @@ $ nixos-rebuild build-vm
$ ./result/bin/run-*-vm
</screen>
The VM does not have use any data from your host system, so your
existing user accounts and home directories will not be
available.</para>
The VM does not have any data from your host system, so your existing
user accounts and home directories will not be available. You can
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>

View file

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

View file

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

View file

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

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")
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
@ -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 --update")
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)
m.upload_file("./amazon-base-config.nix", "/mnt/etc/nixos/configuration.nix")
m.run_command("nixos-install")
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('echo "(hd1) /dev/xvdg" > device.map')
m.run_command('echo -e "root (hd1,0)\nsetup (hd1)" | grub --device-map=device.map --batch')
@ -98,7 +99,7 @@ def check():
m.connect()
volume = m._conn.get_all_volumes([], filters={'attachment.instance-id': m.resource_id, 'attachment.device': "/dev/sdg"})[0]
if args.hvm:
instance = m._conn.run_instances( image_id="ami-6a9e4503"
instance = m._conn.run_instances( image_id="ami-5f491f36"
, instance_type=instance_type
, key_name=args.key_name
, placement=m.zone
@ -185,7 +186,7 @@ f.write(
'''.format(args.region, ami_id, instance_type))
f.close()
test_depl = deployment.create_deployment(db)
test_depl = db.create_deployment()
test_depl.auto_response = "y"
test_depl.name = "ebs-creator-test"
test_depl.nix_exprs = [os.path.abspath("./ebs-test.nix")]

View file

@ -1,9 +1,8 @@
#! /bin/sh -e
nixos=$(nix-instantiate --find-file nixos)
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"
buildAndUploadFor() {
@ -11,13 +10,13 @@ buildAndUploadFor() {
arch="$2"
echo "building $system image..."
nix-build '<nixos>' \
nix-build '<nixpkgs/nixos>' \
-A config.system.build.amazonImage --argstr system "$system" -o ec2-ami
ec2-bundle-image -i ./ec2-ami/nixos.img --user "$AWS_ACCOUNT" --arch "$arch" \
-c "$EC2_CERT" -k "$EC2_PRIVATE_KEY"
for region in eu-west-1 us-east-1 us-west-1 us-west-2; do
for region in eu-west-1; do
echo "uploading $system image for $region..."
name=nixos-$version-$arch-s3

View file

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

View file

@ -31,9 +31,9 @@ in
res = (head defs').value;
in
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)}."
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)}."
else res;
});

View file

@ -6,7 +6,7 @@ let
sysctlOption = mkOptionType {
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.
};
@ -46,7 +46,10 @@ in
before = [ "sysinit.target" "shutdown.target" ];
wantedBy = [ "sysinit.target" "multi-user.target" ];
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 = {
Type = "oneshot";
RemainAfterExit = true;

View file

@ -188,6 +188,20 @@ in
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
# (bootstrap problem!).
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
'';

View file

@ -1,4 +1,6 @@
{pkgs, config, ...}:
{ config, pkgs, ... }:
with pkgs.lib;
let kernelVersion = config.boot.kernelPackages.kernel.version; in
@ -8,9 +10,9 @@ let kernelVersion = config.boot.kernelPackages.kernel.version; in
options = {
networking.enableB43Firmware = pkgs.lib.mkOption {
networking.enableB43Firmware = mkOption {
default = false;
type = pkgs.lib.types.bool;
type = types.bool;
description = ''
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
config = pkgs.lib.mkIf config.networking.enableB43Firmware {
assertions = [ {
assertion = builtins.lessThan 0 (builtins.compareVersions kernelVersion "3.2");
message = "b43 firmware for kernels older than 3.2 not packaged yet!";
} ];
config = mkIf config.networking.enableB43Firmware {
assertions = singleton
{ assertion = lessThan 0 (builtins.compareVersions kernelVersion "3.2");
message = "b43 firmware for kernels older than 3.2 not packaged yet!";
};
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
# user, as expected by nixos-rebuild/nixos-install.
channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}"
{ expr = builtins.readFile ../../../lib/channel-expr.nix; }
{ expr = readFile ../../../lib/channel-expr.nix; }
''
mkdir -p $out/nixos
cp -prd ${pkgs.path} $out/nixos/nixpkgs

View file

@ -32,6 +32,12 @@ with pkgs.lib;
# in the Nix store on the CD.
isoImage.storeContents = [ pkgs.stdenv pkgs.busybox ];
# EFI booting
isoImage.makeEfiBootable = true;
# Add Memtest86+ to the CD.
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
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 ]; }
''
#Let's hope 10M is enough
dd bs=2048 count=5120 if=/dev/zero of="$out"
${pkgs.dosfstools}/sbin/mkfs.vfat "$out"
mmd -i "$out" efi
mmd -i "$out" efi/boot
mmd -i "$out" efi/nixos
mmd -i "$out" loader
mmd -i "$out" loader/entries
mcopy -svi "$out" ${efiDir}/* ::
mmd -i "$out" boot
mcopy -v -i "$out" \
${pkgs.gummiboot}/lib/gummiboot/gummiboot${targetArch}.efi \
::efi/boot/boot${targetArch}.efi
${config.boot.kernelPackages.kernel}/bzImage ::boot/bzImage
mcopy -v -i "$out" \
${config.boot.kernelPackages.kernel}/bzImage ::bzImage
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
${config.system.build.initialRamdisk}/initrd ::boot/initrd
'';
targetArch = if pkgs.stdenv.isi686 then
@ -263,6 +261,12 @@ in
{ source = efiImg;
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;
# The Grub menu.

View file

@ -386,9 +386,6 @@ if ($showHardwareConfig) {
boot.loader.grub.enable = false;
boot.loader.gummiboot.enable = 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
} else {
$bootLoaderConfig = <<EOF;

View file

@ -106,6 +106,8 @@
firebird = 95;
redis = 96;
haproxy = 97;
mongodb = 98;
openldap = 99;
# When adding a uid, make sure it doesn't match an existing gid.
@ -140,7 +142,7 @@
tape = 25;
video = 26;
dialout = 27;
polkituser = 28;
#polkituser = 28; # currently unused, polkitd doesn't need a group
utmp = 29;
davfs2 = 31;
privoxy = 32;
@ -193,6 +195,7 @@
amule = 90;
minidlna = 91;
haproxy = 92;
openldap = 93;
# 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");
# Note: code names must only increase in alphabetical order.
system.nixosCodeName = "Aardvark";
system.nixosCodeName = "Baboon";
# Generate /etc/os-release. See
# http://0pointer.de/public/systemd-man/os-release.html for the

View file

@ -46,7 +46,6 @@
./programs/bash/command-not-found.nix
./programs/blcr.nix
./programs/environment.nix
./programs/gurobi.nix
./programs/info.nix
./programs/shadow.nix
./programs/shell.nix
@ -55,6 +54,7 @@
./programs/venus.nix
./programs/wvdial.nix
./programs/zsh/zsh.nix
./programs/screen.nix
./rename.nix
./security/apparmor.nix
./security/apparmor-suid.nix
@ -91,6 +91,7 @@
./services/databases/virtuoso.nix
./services/games/ghost-one.nix
./services/hardware/acpid.nix
./services/hardware/amd-hybrid-graphics.nix
./services/hardware/bluetooth.nix
./services/hardware/nvidia-optimus.nix
./services/hardware/pcscd.nix
@ -119,7 +120,6 @@
./services/misc/felix.nix
./services/misc/folding-at-home.nix
./services/misc/gpsd.nix
./services/misc/gurobi.nix
./services/misc/nix-daemon.nix
./services/misc/nix-gc.nix
./services/misc/nixos-manual.nix
@ -247,11 +247,11 @@
./system/boot/kexec.nix
./system/boot/loader/efi.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/memtest.nix
./system/boot/loader/gummiboot/gummiboot.nix
./system/boot/loader/init-script/init-script.nix
./system/boot/loader/raspberrypi/raspberrypi.nix
./system/boot/luksroot.nix
./system/boot/modprobe.nix
./system/boot/shutdown.nix
@ -275,8 +275,10 @@
./tasks/network-interfaces.nix
./tasks/scsi-link-power-management.nix
./tasks/swraid.nix
./testing/service-runner.nix
./virtualisation/containers.nix
./virtualisation/libvirtd.nix
#./virtualisation/nova.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 {
default = "*:0,15,30,45";
default = "*:0/15";
type = types.string;
description = ''
Specification (in the format described by
@ -161,13 +161,13 @@ in
'';
systemd.services.venus =
{ description = "Planet Venus, an awesome river of news feed reader";
{ description = "Planet Venus Feed Reader";
path = [ pkgs.venus ];
script = "exec venus-planet ${configFile}";
serviceConfig.User = "${cfg.user}";
serviceConfig.Group = "${cfg.group}";
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.";
};
security.polkit.permissions = mkOption {
security.polkit.extraConfig = mkOption {
type = types.lines;
default = "";
example =
''
[Disallow Users To Suspend]
Identity=unix-group:users
Action=org.freedesktop.upower.*
ResultAny=no
ResultInactive=no
ResultActive=no
/* Log authorization checks. */
polkit.addRule(function(action, subject) {
polkit.log("user " + subject.user + " is attempting action " + action.id + " from PID " + subject.pid);
});
[Allow Anybody To Eject Disks]
Identity=unix-user:*
Action=org.freedesktop.udisks.drive-eject
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
/* Allow any local user to do anything (dangerous!). */
polkit.addRule(function(action, subject) {
if (subject.local) return "yes";
});
'';
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 {
type = types.str;
default = "unix-user:0;unix-group:wheel";
example = "";
type = types.listOf types.str;
default = [ "unix-user:0" "unix-group:wheel" ];
example = [ "unix-user:alice" "unix-group:admin" ];
description =
''
Specifies which users are considered administrators, for those
@ -71,29 +61,20 @@ in
environment.systemPackages = [ pkgs.polkit ];
# The polkit daemon reads action files
environment.pathsToLink = [ "/share/polkit-1/actions" ];
systemd.packages = [ pkgs.polkit ];
environment.etc =
[ # No idea what the "null backend" is, but it seems to need this.
{ source = "${pkgs.polkit}/etc/polkit-1/nullbackend.conf.d";
target = "polkit-1/nullbackend.conf.d";
}
# The polkit daemon reads action/rule files
environment.pathsToLink = [ "/share/polkit-1" ];
# This file determines what users are considered
# "administrators".
{ source = pkgs.writeText "10-nixos.conf"
''
[Configuration]
AdminIdentities=${cfg.adminIdentities}
'';
target = "polkit-1/localauthority.conf.d/10-nixos.conf";
}
# PolKit rules for NixOS.
environment.etc."polkit-1/rules.d/10-nixos.rules".text =
''
polkit.addAdminRule(function(action, subject) {
return [${concatStringsSep ", " (map (i: "\"${i}\"") cfg.adminIdentities)}];
});
{ source = pkgs.writeText "org.nixos.pkla" cfg.permissions;
target = "polkit-1/localauthority/10-vendor.d/org.nixos.pkla";
}
];
${cfg.extraConfig}
''; #TODO: validation on compilation (at least against typos)
services.dbus.packages = [ pkgs.polkit ];
@ -101,24 +82,31 @@ in
security.setuidPrograms = [ "pkexec" ];
security.setuidOwners = singleton
security.setuidOwners = [
{ program = "polkit-agent-helper-1";
owner = "root";
group = "root";
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 =
''
mkdir -p /var/lib/polkit-1/localauthority
chmod 700 /var/lib/polkit-1{/localauthority,}
# Probably no more needed, clean up
rm -rf /var/lib/{polkit-1,PolicyKit}
# Force polkitd to be restarted so that it reloads its
# configuration.
${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";
wantedBy = [ "multi-user.target" ];
unitConfig.RequiresMountsFor = "/var/lib/alsa";
unitConfig.ConditionVirtualization = "!systemd-nspawn";
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;

View file

@ -90,8 +90,9 @@ in
config = mkIf config.services.mongodb.enable {
users.extraUsers = singleton
{ name = cfg.user;
users.extraUsers.mongodb = mkIf (cfg.user == "mongodb")
{ name = "mongodb";
uid = config.ids.uids.mongodb;
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 {
default = "";
description = "
@ -49,10 +59,23 @@ in
after = [ "network.target" ];
preStart = ''
mkdir -p /var/run/slapd
chown -R ${cfg.user}:${cfg.group} /var/run/slapd
mkdir -p /var/db/openldap
chown -R ${cfg.user}:${cfg.group} /var/db/openldap
'';
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}'
ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
log_destination = 'stderr'
port = ${toString cfg.port}
${cfg.extraConfig}
'';
@ -63,9 +64,9 @@ in
port = mkOption {
type = types.int;
default = "5432";
default = 5432;
description = ''
Port for PostgreSQL.
The port on which PostgreSQL listens.
'';
};
@ -105,7 +106,9 @@ in
type = types.bool;
default = false;
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.
if ! test -e ${cfg.dataDir}; then
mkdir -m 0700 -p ${cfg.dataDir}
chown -R postgres ${cfg.dataDir}
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
if [ "$(id -u)" = 0 ]; then
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
touch "${cfg.dataDir}/.first_startup"
fi
@ -203,6 +211,7 @@ in
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
# http://www.postgresql.org/docs/current/static/server-shutdown.html
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
# receiving systemd's SIGINT.

View file

@ -110,6 +110,7 @@ in
exec = "acpid --confdir ${acpiConfDir}";
unitConfig.ConditionVirtualization = "!systemd-nspawn";
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 ];
systemd.services."dbus-org.bluez" = {
description = "Bluetooth service";
description = "Bluetooth Service";
serviceConfig = {
Type = "dbus";
BusName = "org.bluez";

View file

@ -209,7 +209,7 @@ in
###### implementation
config = {
config = mkIf (!config.boot.isContainer) {
services.udev.extraRules = nixosRules;
@ -231,9 +231,16 @@ in
boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}";
system.activationScripts.clearHotplug =
system.activationScripts.udevd =
''
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 ];
unitConfig.ConditionVirtualization = "!systemd-nspawn";
exec =
"klogd -c 1 -2 -n " +
"-k $(dirname $(readlink -f /run/booted-system/kernel))/System.map";

View file

@ -3,72 +3,8 @@
with pkgs.lib;
let
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
{
@ -78,48 +14,45 @@ in
services.logstash = {
enable = mkOption {
default = false;
description = ''
Enable logstash.
'';
description = "Enable logstash";
};
inputConfig = mkOption {
default = {};
description = ''
An attribute set (or an expression generated by mkNameValuePairs)
representing a logstash configuration's input section.
Logstash configs are name-value pairs, where values can be bools,
strings, numbers, arrays, hashes, or other name-value pairs,
and names are strings that can be repeated. Name-value pairs with no
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.
default = ''stdin { type => "example" }'';
description = "Logstash input configuration";
example = ''
# Read from journal
pipe {
command => "${pkgs.systemd}/bin/journalctl -f -o json"
type => "syslog" codec => json {}
}
'';
apply = mergeConfigs;
};
filterConfig = mkOption {
default = {};
description = ''
An attribute set (or an expression generated by mkNameValuePairs)
representing a logstash configuration's filter section.
See inputConfig description for details.
default = ''noop {}'';
description = "logstash filter configuration";
example = ''
if [type] == "syslog" {
# 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 {
default = {};
description = ''
An attribute set (or an expression generated by mkNameValuePairs)
representing a logstash configuration's output section.
See inputConfig description for details.
default = ''stdout { debug => true debug_format => "json"}'';
description = "Logstash output configuration";
example = ''
redis { host => "localhost" data_type => "list" key => "logstash" codec => json }
elasticsearch { embedded => true }
'';
apply = mergeConfigs;
};
};
};
@ -127,35 +60,26 @@ in
###### implementation
config = mkMerge [ {
lib.logstash = {
mkFloat = stringRep: { __type = "float"; value = stringRep; };
mkHash = attrs: { __type = "hash"; value = attrs; };
mkNameValuePairs = mergeConfigs;
};
} ( mkIf cfg.enable {
config = mkIf cfg.enable {
systemd.services.logstash = with pkgs; {
description = "Logstash daemon";
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" ''
input {
${exprToConfig cfg.inputConfig}
}
filter {
${cfg.filterConfig}
}
filter {
${exprToConfig cfg.filterConfig}
}
output {
${exprToConfig cfg.outputConfig}
}
''} &> /var/log/logstash.log";
output {
${cfg.outputConfig}
}
''}";
};
};
})];
};
}

View file

@ -15,6 +15,7 @@ let
enablePostgreSQLDatabase = config.services.postgresql.enable;
enableSubversionRepository = config.services.svnserve.enable;
enableTomcatWebApplication = config.services.tomcat.enable;
enableMongoDatabase = config.services.mongodb.enable;
});
in
@ -110,7 +111,7 @@ in
// optionalAttrs (config.services.tomcat.enable) { tomcatPort = 8080; }
// optionalAttrs (config.services.svnserve.enable) { svnBaseDir = config.services.svnserve.svnBaseDir; }
// 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.mysql.enable "mysql.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;
path = [ pkgs.nix pkgs.disnix ];
script =
''
export HOME=/root
disnix-service --dysnomia-modules-dir=${dysnomia}/libexec/dysnomia
'';
path = [ pkgs.nix pkgs.disnix pkgs.dysnomia ];
environment = {
HOME = "/root";
};
exec = "disnix-service";
};
} // optionalAttrs cfg.publishAvahi {
disnixAvahi =
@ -150,7 +152,7 @@ in
${concatMapStrings (infrastructureAttrName:
let infrastructureAttrValue = getAttr infrastructureAttrName (cfg.infrastructure);
in
if builtins.isInt infrastructureAttrValue then
if isInt infrastructureAttrValue then
''${infrastructureAttrName}=${toString infrastructureAttrValue} \
''
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";
wantedBy = [ "sockets.target" ];
before = [ "multi-user.target" ];
unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-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"; };
unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket/";
serviceConfig =
{ ExecStart = "@${nix}/bin/nix-daemon nix-daemon --daemon";
KillMode = "process";
@ -331,10 +334,8 @@ in
''
# Set up secure multi-user builds: non-root users build through the
# Nix daemon.
if test "$USER" != root; then
if [ "$USER" != root -o ! -w /nix/var/nix/db ]; then
export NIX_REMOTE=daemon
else
export NIX_REMOTE=
fi
'';

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,7 +19,7 @@ let
knownHostsFile = pkgs.writeText "ssh_known_hosts" (
flip concatMapStrings knownHosts (h:
"${concatStringsSep "," h.hostNames} ${builtins.readFile h.publicKeyFile}"
"${concatStringsSep "," h.hostNames} ${readFile h.publicKeyFile}"
)
);
@ -59,7 +59,7 @@ let
mode = "0444";
source = pkgs.writeText "${u.name}-authorized_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:

View file

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

View file

@ -8,11 +8,14 @@ let
queuelen = if cfg.queuelen == null then "" else "-q ${toString cfg.queuelen}";
# Duplicate code, also found in cron.nix. Needs deduplication.
systemCronJobs =
''
SHELL=${pkgs.bash}/bin/bash
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
${pkgs.lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)}
'';

View file

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

View file

@ -15,7 +15,7 @@ let
toOption = x:
if x == true then "true"
else if x == false then "false"
else if builtins.isInt x then toString x
else if isInt x then toString x
else toString ''\"${x}\"'';
# 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;
extraModules = attrByPath ["extraModules"] [] mainCfg;
extraForeignModules = filter builtins.isAttrs extraModules;
extraApacheModules = filter (x: !(builtins.isAttrs x)) extraModules; # I'd prefer using builtins.isString here, but doesn't exist yet
extraForeignModules = filter isAttrs extraModules;
extraApacheModules = filter isString extraModules;
makeServerInfo = cfg: {
@ -628,10 +628,10 @@ in
preStart =
''
mkdir -m 0750 -p ${mainCfg.stateDir}
chown root.${mainCfg.group} ${mainCfg.stateDir}
[ $(id -u) != 0 ] || chown root.${mainCfg.group} ${mainCfg.stateDir}
${optionalString version24 ''
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}
@ -659,6 +659,7 @@ in
serviceConfig.ExecStart = "@${httpd}/bin/httpd httpd -f ${httpdConf}";
serviceConfig.ExecStop = "${httpd}/bin/httpd -f ${httpdConf} -k graceful-stop";
serviceConfig.Type = "forking";
serviceConfig.PIDFile = "${mainCfg.stateDir}/httpd.pid";
serviceConfig.Restart = "always";
};

View file

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

View file

@ -4,7 +4,7 @@ with pkgs.lib;
let
cfg = config.services.nginx;
nginx = pkgs.nginx.override { fullWebDAV = cfg.fullWebDAV; };
nginx = cfg.package;
configFile = pkgs.writeText "nginx.conf" ''
user ${cfg.user} ${cfg.group};
daemon off;
@ -22,6 +22,13 @@ in
";
};
package = mkOption {
default = pkgs.nginx;
description = "
Nginx package to use.
";
};
config = mkOption {
default = "events {}";
description = "
@ -46,10 +53,6 @@ in
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
# determines the default: later modules (if enabled) are preferred.
# E.g., if KDE is enabled, it supersedes xterm.
imports = [ ./none.nix ./xterm.nix ./xfce.nix ./gnome.nix ./kde4.nix ./e17.nix ];
imports = [ ./none.nix ./xterm.nix ./xfce.nix ./kde4.nix ./e17.nix ];
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.gvfs
pkgs.xfce.xfce4_appfinder
pkgs.xfce.tumbler
]
++ optional config.powerManagement.enable pkgs.xfce.xfce4_power_manager;

View file

@ -44,7 +44,9 @@ let
# since presumably the desktop environment will handle these.
if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
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
''}

View file

@ -57,6 +57,13 @@ let cfg = config.services.xserver.synaptics; in
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 {
default = false;
example = true;
@ -104,10 +111,13 @@ let cfg = config.services.xserver.synaptics; in
Option "MinSpeed" "${cfg.minSpeed}"
Option "MaxSpeed" "${cfg.maxSpeed}"
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"''}
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 "HorizTwoFingerScroll" "${if cfg.twoFingerScroll then "1" else "0"}"
Option "VertEdgeScroll" "${if cfg.vertEdgeScroll then "1" else "0"}"

View file

@ -17,27 +17,17 @@ let
#! ${pkgs.stdenv.shell}
export XKB_BINDIR=${pkgs.xorg.xkbcomp}/bin
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
{
config = {
services.xserver.enable = true;
services.xserver.videoDrivers = [];
# Enable KDM. Any display manager will do as long as it supports XDMCP.
services.xserver.displayManager.kdm.enable = true;
@ -52,13 +42,38 @@ in
Xaccess=${pkgs.writeText "Xaccess" "localhost"}
'';
services.xinetd.enable = true;
services.xinetd.services = singleton
{ name = "x11vnc";
port = 5900;
unlisted = true;
user = "root";
server = "${x11vncWrapper}/bin/x11vnc-wrapper";
networking.firewall.allowedTCPPorts = [ 5900 ];
systemd.sockets.terminal-server =
{ description = "Terminal Server Socket";
wantedBy = [ "sockets.target" ];
before = [ "multi-user.target" ];
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 {
type = types.lines;
default = "";
@ -586,6 +598,7 @@ in
''
Section "ServerFlags"
Option "AllowMouseOpenFail" "on"
${cfg.serverFlagsSection}
EndSection
Section "Module"

View file

@ -71,7 +71,7 @@ in
${
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';
in textClosureMap id (withHeadlines) (attrNames withHeadlines)
}

View file

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

View file

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

View file

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

View file

@ -66,7 +66,7 @@ with pkgs.lib;
###### implementation
config = {
config = mkIf (!config.boot.isContainer) {
environment.etc = singleton
{ 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
# clock on shutdown.
systemd.units."save-hwclock.service" =
{ wantedBy = [ "shutdown.target" ];
systemd.services.save-hwclock =
{ description = "Save Hardware Clock";
text =
''
[Unit]
Description=Save Hardware Clock
DefaultDependencies=no
Before=shutdown.target
wantedBy = [ "shutdown.target" ];
[Service]
Type=oneshot
ExecStart=${pkgs.utillinux}/sbin/hwclock --systohc ${if config.time.hardwareClockInLocalTime then "--localtime" else "--utc"}
'';
unitConfig = {
DefaultDependencies = false;
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";

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.initialRamdisk = initialRamdisk;

View file

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

View file

@ -160,16 +160,48 @@ let
};
serviceConfig = { name, config, ... }: {
config = {
# Default path for systemd services. Should be quite minimal.
path =
[ pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
systemd
];
};
config = mkMerge
[ { # Default path for systemd services. Should be quite minimal.
path =
[ pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
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, ... }: {
@ -223,41 +255,10 @@ let
${attrsToSection def.unitConfig}
[Service]
Environment=PATH=${def.path}
Environment=LD_LIBRARY_PATH=
${let env = cfg.globalEnvironment // def.environment;
in concatMapStrings (n: "Environment=\"${n}=${getAttr n env}\"\n") (attrNames env)}
${optionalString (!def.restartIfChanged) "X-RestartIfChanged=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}
'';
};
@ -311,8 +312,6 @@ let
'';
};
nixosUnits = mapAttrsToList makeUnit cfg.units;
units = pkgs.runCommand "units" { preferLocalBuild = true; }
''
mkdir -p $out
@ -338,7 +337,7 @@ let
done
done
for i in ${toString nixosUnits}; do
for i in ${toString (mapAttrsToList (n: v: v.unit) cfg.units)}; do
ln -s $i/* $out/
done
@ -348,14 +347,14 @@ let
${concatStrings (mapAttrsToList (name: unit:
concatMapStrings (name2: ''
mkdir -p $out/${name2}.wants
ln -sfn ../${name} $out/${name2}.wants/
mkdir -p $out/'${name2}.wants'
ln -sfn '../${name}' $out/'${name2}.wants'/
'') unit.wantedBy) cfg.units)}
${concatStrings (mapAttrsToList (name: unit:
concatMapStrings (name2: ''
mkdir -p $out/${name2}.requires
ln -sfn ../${name} $out/${name2}.requires/
mkdir -p $out/'${name2}.requires'
ln -sfn '../${name}' $out/'${name2}.requires'/
'') unit.requiredBy) cfg.units)}
ln -s ${cfg.defaultUnit} $out/default.target
@ -387,32 +386,41 @@ in
description = "Definition of systemd units.";
default = {};
type = types.attrsOf types.optionSet;
options = {
text = mkOption {
type = types.str;
description = "Text of this systemd unit.";
options = { name, config, ... }:
{ options = {
text = mkOption {
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 {
@ -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 {
default = "";
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 {
default = "";
type = types.str;
type = types.lines;
example = "HandleLidSwitch=ignore";
description = ''
Extra config options for systemd-logind. See man logind.conf for
@ -555,6 +583,7 @@ in
environment.etc."systemd/system.conf".text =
''
[Manager]
${config.systemd.extraConfig}
'';
environment.etc."systemd/journald.conf".text =
@ -566,6 +595,7 @@ in
ForwardToConsole=yes
TTYPath=${config.services.journald.console}
''}
${config.services.journald.extraConfig}
'';
environment.etc."systemd/logind.conf".text =
@ -585,13 +615,6 @@ in
mkdir -p /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
# groups, in addition to those in the systemd-journal group.
# Users can always read their own journals.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -31,6 +31,8 @@ with pkgs.lib;
task = true;
unitConfig.ConditionPathIsReadWrite = "/sys/class/scsi_host";
script = ''
shopt -s nullglob
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 ];
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
rm -f /var/run/libvirtd.pid
mkdir -p /var/lib/libvirt -m 700
mkdir -p /var/lib/libvirt/dnsmasq -m 700
mkdir -p /var/lib/libvirt
mkdir -p /var/lib/libvirt/dnsmasq
chmod 755 /var/lib/libvirt
chmod 755 /var/lib/libvirt/dnsmasq
# Libvirt unfortunately writes mutable state (such as
# runtime changes to VM, network or filter configurations)
@ -98,6 +101,19 @@ in
mkdir -p /etc/$(dirname $i) -m 755
cp -fpd ${pkgs.libvirt}/etc/$i /etc/$i
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'';

View file

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

View file

@ -107,4 +107,9 @@ with pkgs.lib;
boot.loader.grub.device = "/dev/sda";
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 =
{ description = "Xen control daemon";
{ description = "Xen Control Daemon";
startOn = "stopped udevtrigger";

View file

@ -123,11 +123,13 @@ in rec {
inherit system;
});
/*
iso_minimal_new_kernel = forAllSystems (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-minimal-new-kernel.nix;
type = "minimal-new-kernel";
inherit system;
});
*/
iso_graphical = forAllSystems (system: makeIso {
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
# that might support more hardware.
/*
iso_new_kernel = forAllSystems (system: makeIso {
module = ./modules/installer/cd-dvd/installation-cd-new-kernel.nix;
type = "new-kernel";
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).

View file

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

View file

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