diff --git a/doc/manual/development.xml b/doc/manual/development.xml
index f4d68526c5e..e79114d1785 100644
--- a/doc/manual/development.xml
+++ b/doc/manual/development.xml
@@ -7,6 +7,230 @@
NixOS.
+
+
+Extending NixOS
+
+A unique syntax is used to express all system, hardware, computer and
+ service configurations. This syntax helps for reading and writing new
+ configuration files. It is coming with some extra strategies defined in
+ NixPkgs which are used to merge and evaluate all configuration files.
+
+ A configuration file is the same as your own computer
+ configuration.
+
+Usual configuration file
+
+{pkgs, config, ...}:
+
+###### interface
+let
+ inherit (pkgs.lib) mkOption;
+
+ options = {
+ services = {
+ locate = {
+
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = ''
+ If enabled, NixOS will periodically update the database of
+ files used by the locate command.
+ '';
+ };
+
+ period = mkOption {
+ default = "15 02 * * *";
+ description = ''
+ This option defines (in the format used by cron) when the
+ locate database is updated.
+ The default is to update at 02:15 (at night) every day.
+ '';
+ };
+
+ };
+
+ };
+ };
+in
+
+###### implementation
+let
+ cfg = config.services.locate;
+ inherit (pkgs.lib) mkIf mkThenElse;
+
+ locatedb = "/var/cache/locatedb";
+ logfile = "/var/log/updatedb";
+ cmd = "root updatedb --localuser=nobody --output=${locatedb} > ${logfile}";
+in
+
+mkIf cfg.enable {
+ require = [
+ options
+
+ # config.services.cron
+ (import ../../upstart-jobs/cron.nix)
+ ];
+
+ services = {
+ cron = {
+ systemCronJobs = mkThenElse {
+ thenPart = "${cfg.period} root ${cmd}";
+ elsePart = "";
+ };
+ };
+ };
+}
+
+
+ shows the configuration
+ file for the locate service which uses cron to update the
+ database at some dates which can be defined by the user. This nix
+ expression is coming
+ from upstart-jobs/cron/locate.nix. It shows a simple
+ example of a service that can be either distributed on many computer that
+ are using the same configuration or to shared with the community. This
+ file is divided in two with the interface and the implementation. Both
+ the interface and the implementation declare a configuration
+ set.
+
+
+
+
+
+ This line declares the arguments of the configuration file. You
+ can omit this line if there is no reference to pkgs
+ and config inside the configuration file.
+
+ The argument pkgs refers to NixPkgs and allow
+ you to access all attributes contained inside it. In this
+ example pkgs is used to retrieve common functions to
+ ease the writing of configuration files
+ like mkOption, mkIf
+ and mkThenElse.
+
+ The argument config corresponds to the whole
+ NixOS configuration. This is a set which is build by merging all
+ configuration files imported to set up the system. Thus all options
+ declared are contained inside this variable. In this
+ example config is used to retrieve the status of
+ the enable flag. The important point of this
+ argument is that it contains either the result of the merge of different
+ settings or the default value, therefore you cannot assume
+ that is always false
+ because it may have been defined in another configuration file.
+
+
+
+
+
+ This line is used to import a function that is useful for
+ writing this configuration file.
+
+
+
+
+
+ The variable options is
+ a configuration set which is only used to declare
+ options with the function mkOption imported
+ from pkgs/lib/default.nix. Options may contained
+ any attribute but only the following have a special
+ meaning: default, example,
+ description, merge
+ and apply.
+
+ The merge attribute is used to merge all values
+ defined in all configuration files and this function return a value
+ which has the same type as the default value. If the merge function is
+ not defined, then a default function
+ (pkgs.lib.mergeDefaultOption) is used to merge
+ values. The merge attribute is a function which
+ expect two arguments: the location of the option and the list of values
+ which have to be merged.
+
+ The apply attribute is a function used to
+ process the option. Thus the value return
+ by would be
+ the result of the apply function called with either
+ the default value or the result of
+ the merge function.
+
+
+
+
+
+ This line is a common trick used to reduce the amount of
+ writing. In this case cfg is just a sugar over
+
+
+
+
+
+
+ This line is used to declare a special IF
+ statement. If you had put a usual IF statement
+ here, with the same condition, then you will get an infinite loop. The
+ reason is that your condition ask for the value of the
+ option but in order to
+ get this value you have to evaluate all configuration sets including the
+ configuration set contained inside your file.
+
+ To remove this extra complexity, mkIf has been
+ introduced to get rid of possible infinite loop and to factor your
+ writing.
+
+
+
+
+
+ The attribute require is the only special
+ option that exists. It is used to embed all option declarations that
+ are required by your configuration file and it is also used to provide
+ the options that you are declaring.
+
+ This attribute is processed
+ with pkgs.lib.uniqFlatten to collect all
+ configuration files that are used by your system and it avoid the
+ insertion of duplicated elements by comparing the configuration set codes.
+
+ Currently, the file configuration.nix
+ implicitly embeds system/options.nix. If you need
+ a special configuration file, then you will have to add similar lines
+ to your computer configuration.
+
+
+
+
+
+ As mkIf does not need
+ any then part or else part,
+ then you can specify one on each option definition with the
+ function mkThenElse.
+
+ To avoid a lot of mkThenElse with empty
+ else part, a sugar has been added to infer the
+ corresponding empty-value of your option when the
+ function mkThenElse is not used.
+
+ If your then part
+ and else part are identical, then you should use
+ the function mkAlways to ignore the condition.
+
+ If you need to add another condition, then you can add mkIf to on
+ the appropriate location. Thus the then part will
+ only be used if all conditions declared with mkIf
+ are satisfied.
+
+
+
+
+
+
+
+
+
Building specific parts of NixOS
diff --git a/installer/nixos-hardware-scan.pl b/installer/nixos-hardware-scan.pl
index e3277fa035d..d21e92cd51b 100644
--- a/installer/nixos-hardware-scan.pl
+++ b/installer/nixos-hardware-scan.pl
@@ -4,6 +4,7 @@ use File::Spec;
use File::Basename;
+my @requireList = ();
my @kernelModules = ();
my @initrdKernelModules = ();
@@ -56,8 +57,6 @@ push @kernelModules, "kvm-amd" if hasCPUFeature "svm";
# modules are auto-detected so we don't need to list them here.
# However, some are needed in the initrd to boot the system.
-my $enableIntel2200BGFirmware = "false";
-my $enableIntel3945ABGFirmware = "false";
my $videoDriver = "vesa";
sub pciCheck {
@@ -97,11 +96,13 @@ sub pciCheck {
# Can't rely on $module here, since the module may not be loaded
# due to missing firmware. Ideally we would check modules.pcimap
# here.
- $enableIntel2200BGFirmware = "true" if $vendor eq "0x8086" &&
+ push @requireList, "(import ./configurations/hardware/network/Intel2200BG.nix)" if
+ $vendor eq "0x8086" &&
($device eq "0x1043" || $device eq "0x104f" || $device eq "0x4220" ||
$device eq "0x4221" || $device eq "0x4223" || $device eq "0x4224");
- $enableIntel3945ABGFirmware = "true" if $vendor eq "0x8086" &&
+ push @requireList, "(import ./configurations/hardware/network/Intel3945ABG.nix)" if
+ $vendor eq "0x8086" &&
($device eq "0x4229" || $device eq "0x4230" ||
$device eq "0x4222" || $device eq "0x4227");
@@ -197,14 +198,26 @@ sub toNixExpr {
return $res;
}
+sub multiLineList {
+ my $indent = shift;
+ my $res = "";
+ foreach my $s (@_) {
+ $res .= "\n$indent $s";
+ }
+ $res .= "\nindent";
+ return $res;
+}
+
my $initrdKernelModules = toNixExpr(removeDups @initrdKernelModules);
my $kernelModules = toNixExpr(removeDups @kernelModules);
-
+my $requireList = multiLineList(" ", removeDups @requireList);
## This is a generated file. Do not modify!
## Make changes to /etc/nixos/configuration.nix instead.
print <= 2.6.27 provides firmware
+ addFirmware = [ "${kernel}/lib/firmware" ];
+ };
+ };
+}
diff --git a/system/options.nix b/system/options.nix
index fbb316dc53a..7c4b5def367 100644
--- a/system/options.nix
+++ b/system/options.nix
@@ -1,33 +1,7 @@
{pkgs, config, ...}:
let
- inherit (pkgs.lib) mkOption;
- inherit (builtins) head tail;
-
- obsolete = what: f: name:
- if builtins ? trace then
- builtins.trace "${name}: Obsolete ${what}." f name
- else f name;
-
- obsoleteMerge =
- obsolete "option" pkgs.lib.mergeDefaultOption;
-
- # temporary modifications.
- # backward here means that expression could either be a value or a
- # function which expects to have a pkgs argument.
- optionalPkgs = name: x:
- if builtins.isFunction x
- then obsolete "notation" (name: x pkgs) name
- else x;
-
- backwardPkgsFunListMerge = name: list:
- pkgs.lib.concatMap (optionalPkgs name) list;
-
- backwardPkgsFunMerge = name: list:
- if list != [] && tail list == []
- then optionalPkgs name (head list)
- else abort "${name}: Defined at least twice.";
-
+ inherit (pkgs.lib) mkOption mergeOneOption;
in
{
@@ -64,51 +38,6 @@ in
";
};
- kernelPackages = mkOption {
- default = pkgs.kernelPackages;
- example = pkgs.kernelPackages_2_6_25;
- merge = backwardPkgsFunMerge;
- description = "
- This option allows you to override the Linux kernel used by
- NixOS. Since things like external kernel module packages are
- tied to the kernel you're using, it also overrides those.
- This option is a function that takes Nixpkgs as an argument
- (as a convenience), and returns an attribute set containing at
- the very least an attribute kernel.
- Additional attributes may be needed depending on your
- configuration. For instance, if you use the NVIDIA X driver,
- then it also needs to contain an attribute
- nvidiaDrivers.
- ";
- };
-
- kernelParams = mkOption {
- default = [
- "selinux=0"
- "apm=on"
- "acpi=on"
- "vga=0x317"
- "console=tty1"
- "splash=verbose"
- ];
- description = "
- The kernel parameters. If you want to add additional
- parameters, it's best to set
- .
- ";
- };
-
- extraKernelParams = mkOption {
- default = [
- ];
- example = [
- "debugtrace"
- ];
- description = "
- Additional user-defined kernel parameters.
- ";
- };
-
hardwareScan = mkOption {
default = true;
description = "
@@ -121,89 +50,8 @@ in
";
};
- extraModulePackages = mkOption {
- default = [];
- # !!! example = [pkgs.aufs pkgs.nvidiaDrivers];
- description = ''
- A list of additional packages supplying kernel modules.
- '';
- merge = backwardPkgsFunListMerge;
- };
-
- kernelModules = mkOption {
- default = [];
- description = "
- The set of kernel modules to be loaded in the second stage of
- the boot process. That is, these modules are not included in
- the initial ramdisk, so they'd better not be required for
- mounting the root file system. Add them to
- if they are.
- ";
- };
-
initrd = {
- kernelModules = mkOption {
- default = [
- # Note: most of these (especially the SATA/PATA modules)
- # shouldn't be included by default since nixos-hardware-scan
- # detects them, but I'm keeping them for now for backwards
- # compatibility.
-
- # Some SATA/PATA stuff.
- "ahci"
- "sata_nv"
- "sata_via"
- "sata_sis"
- "sata_uli"
- "ata_piix"
- "pata_marvell"
-
- # Standard SCSI stuff.
- "sd_mod"
- "sr_mod"
-
- # Standard IDE stuff.
- "ide_cd"
- "ide_disk"
- "ide_generic"
-
- # Filesystems.
- "ext3"
-
- # Support USB keyboards, in case the boot fails and we only have
- # a USB keyboard.
- "ehci_hcd"
- "ohci_hcd"
- "usbhid"
-
- # LVM.
- "dm_mod"
- ];
- description = "
- The set of kernel modules in the initial ramdisk used during the
- boot process. This set must include all modules necessary for
- mounting the root device. That is, it should include modules
- for the physical device (e.g., SCSI drivers) and for the file
- system (e.g., ext3). The set specified here is automatically
- closed under the module dependency relation, i.e., all
- dependencies of the modules list here are included
- automatically. If you want to add additional
- modules, it's best to set
- .
- ";
- };
-
- extraKernelModules = mkOption {
- default = [];
- description = "
- Additional kernel modules for the initial ramdisk. These are
- loaded before the modules listed in
- , so they take
- precedence.
- ";
- };
-
allowMissing = mkOption {
default = false;
description = ''
@@ -295,17 +143,7 @@ in
merge = pkgs.lib.mergeListOption;
# Convert the list of path to only one path.
- apply = list: pkgs.aggregateModules (
- let
- kernelPackages = config.boot.kernelPackages;
- kernel = kernelPackages.kernel;
- in
- [ kernel ]
- ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007
- ++ config.boot.extraModulePackages
- # should only keep this one, other have to be set by the option owners.
- ++ list
- );
+ apply = pkgs.aggregateModules;
};
sbin = {
@@ -345,21 +183,6 @@ in
};
};
- # Hm, this sounds like a catch-all...
- hardware = {
-
- enableGo7007 = mkOption {
- default = false;
- merge = obsoleteMerge;
- description = ''
- Enable this option to get support for the WIS GO7007SB
- multi-format video encoder, which is used in a number of
- devices such as the Plextor ConvertX TV402U USB TV device.
- '';
- };
-
- };
-
networking = {
@@ -411,45 +234,6 @@ in
";
};
- enableIntel2200BGFirmware = mkOption {
- default = false;
- merge = obsoleteMerge;
- description = "
- Turn on this option if you want firmware for the Intel
- PRO/Wireless 2200BG to be loaded automatically. This is
- required if you want to use this device. Intel requires you to
- accept the license for this firmware, see
- .
- ";
- };
-
- enableIntel3945ABGFirmware = mkOption {
- default = false;
- merge = obsoleteMerge;
- description = "
- This option enables automatic loading of the firmware for the Intel
- PRO/Wireless 3945ABG.
- ";
- };
-
- enableIntel4965AGNFirmware = mkOption {
- default = false;
- merge = obsoleteMerge;
- description = "
- This option enables automatic loading of the firmware for the Intel
- PRO/Wireless 4965AGN.
- ";
- };
-
- enableZydasZD1211Firmware = mkOption {
- default = false;
- merge = obsoleteMerge;
- description = "
- This option enables automatic loading of the firmware for the Zydas
- ZyDAS ZD1211(b) 802.11a/b/g USB WLAN chip.
- ";
- };
-
localCommands = mkOption {
default = "";
example = "text=anything; echo You can put $text here.";
@@ -2346,7 +2130,6 @@ in
extraPackages = mkOption {
default = [];
example = [pkgs.firefox pkgs.thunderbird];
- merge = backwardPkgsFunListMerge;
description = "
This option allows you to add additional packages to the system
path. These packages are automatically available to all users,
@@ -2363,7 +2146,7 @@ in
nix = mkOption {
default = pkgs.nixUnstable;
example = pkgs.nixCustomFun /root/nix.tar.gz;
- merge = backwardPkgsFunMerge;
+ merge = mergeOneOption;
description = "
Use non-default Nix easily. Be careful, though, not to break everything.
";
@@ -2405,6 +2188,7 @@ in
require = [
# boot (is it the right place ?)
+ (import ../system/kernel.nix)
(import ../boot/boot-stage-2.nix)
(import ../installer/grub.nix)
@@ -2435,7 +2219,7 @@ in
(import ../upstart-jobs/hal.nix)
(import ../upstart-jobs/gpm.nix)
(import ../upstart-jobs/nagios/default.nix)
- (import ../upstart-jobs/xserver.nix)
+ (import ../upstart-jobs/xserver/default.nix)
(import ../upstart-jobs/zabbix-agent.nix)
(import ../upstart-jobs/zabbix-server.nix)
(import ../upstart-jobs/disnix.nix)
diff --git a/system/system-options.nix b/system/system-options.nix
index 97a9e05d4f5..b1688cdda80 100644
--- a/system/system-options.nix
+++ b/system/system-options.nix
@@ -287,7 +287,7 @@ in
# Set the host name. Don't clear it if it's not configured in the
# NixOS configuration, since it may have been set by dhclient in the
# meantime.
- ${if config.networking.hostName == "" then
+ ${if config.networking.hostName != "" then
''hostname "${config.networking.hostName}"''
else ''
# dhclient won't do anything if the hostname isn't empty.
diff --git a/system/system.nix b/system/system.nix
index 75087708b83..78b6a0a6dee 100644
--- a/system/system.nix
+++ b/system/system.nix
@@ -11,14 +11,11 @@ rec {
systemPathList
];
- noOption = name: values:
- abort "${name}: Used without option declaration.";
-
# Make a configuration object from which we can retrieve option
# values.
config =
pkgs.lib.fixOptionSets
- (pkgs.lib.mergeOptionSets noOption)
+ pkgs.lib.newMergeOptionSets
pkgs configComponents;
optionDeclarations =
@@ -158,7 +155,6 @@ rec {
++ pkgs.lib.optional config.networking.defaultMailServer.directDelivery pkgs.ssmtp
++ config.environment.extraPackages
++ pkgs.lib.optional config.fonts.enableFontDir fontDir
- ++ pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007
# NSS modules need to be in `systemPath' so that (i) the builder
# chroot gets to seem them, and (ii) applications can benefit from
diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix
index 3633dee63e7..f66d1106622 100644
--- a/upstart-jobs/default.nix
+++ b/upstart-jobs/default.nix
@@ -147,16 +147,8 @@ let
inherit modprobe config;
inherit (pkgs) stdenv writeText substituteAll udev procps;
inherit (pkgs.lib) cleanSource;
- firmwareDirs =
- pkgs.lib.optional config.networking.enableIntel2200BGFirmware pkgs.ipw2200fw
- ++ pkgs.lib.optional config.networking.enableIntel3945ABGFirmware pkgs.iwlwifi3945ucode
- ++ pkgs.lib.optional config.networking.enableIntel4965AGNFirmware kernelPackages.iwlwifi4965ucode
- ++ pkgs.lib.optional config.networking.enableZydasZD1211Firmware pkgs.zd1211fw
- ++ pkgs.lib.optional config.hardware.enableGo7007 "${kernelPackages.wis_go7007}/firmware"
- ++ config.services.udev.addFirmware;
- extraUdevPkgs =
- pkgs.lib.optional config.hardware.enableGo7007 kernelPackages.wis_go7007
- ++ config.services.udev.addUdevPkgs;
+ firmwareDirs = config.services.udev.addFirmware;
+ extraUdevPkgs = config.services.udev.addUdevPkgs;
})
# Makes LVM logical volumes available.
diff --git a/upstart-jobs/disnix.nix b/upstart-jobs/disnix.nix
index b87784ec067..52699c31daf 100644
--- a/upstart-jobs/disnix.nix
+++ b/upstart-jobs/disnix.nix
@@ -1,5 +1,5 @@
# Disnix server
-{config, pkgs}:
+{config, pkgs, ...}:
###### interface
let
diff --git a/upstart-jobs/fcron.nix b/upstart-jobs/fcron.nix
index 97d259c65e1..5dd61e669d3 100644
--- a/upstart-jobs/fcron.nix
+++ b/upstart-jobs/fcron.nix
@@ -1,4 +1,4 @@
-{pkgs, config}:
+{pkgs, config, ...}:
###### interface
let
diff --git a/upstart-jobs/xserver.nix b/upstart-jobs/xserver/default.nix
similarity index 60%
rename from upstart-jobs/xserver.nix
rename to upstart-jobs/xserver/default.nix
index 0e204282c14..0a7a70c7175 100644
--- a/upstart-jobs/xserver.nix
+++ b/upstart-jobs/xserver/default.nix
@@ -66,6 +66,7 @@ let
";
};
+/*
sessionType = mkOption {
default = "gnome";
example = "xterm";
@@ -91,14 +92,6 @@ let
";
};
- renderingFlag = mkOption {
- default = "";
- example = "--indirect-rendering";
- description = "
- Possibly pass --indierct-rendering to Compiz.
- ";
- };
-
sessionStarter = mkOption {
example = "${pkgs.xterm}/bin/xterm -ls";
description = "
@@ -107,6 +100,7 @@ let
is empty.
";
};
+*/
startSSHAgent = mkOption {
default = true;
@@ -118,41 +112,6 @@ let
";
};
- slim = {
-
- theme = mkOption {
- default = null;
- example = pkgs.fetchurl {
- url = http://download.berlios.de/slim/slim-wave.tar.gz;
- sha256 = "0ndr419i5myzcylvxb89m9grl2xyq6fbnyc3lkd711mzlmnnfxdy";
- };
- description = "
- The theme for the SLiM login manager. If not specified, SLiM's
- default theme is used. See for a
- collection of themes.
- ";
- };
-
- defaultUser = mkOption {
- default = "";
- example = "login";
- description = "
- The default user to load. If you put a username here you
- get it automatically loaded into the username field, and
- the focus is placed on the password.
- ";
- };
-
- hideCursor = mkOption {
- default = false;
- example = true;
- description = "
- Hide the mouse cursor on the login screen.
- ";
- };
- };
-
isClone = mkOption {
default = true;
example = false;
@@ -327,7 +286,6 @@ let
# Abbreviations.
cfg = config.services.xserver;
xorg = cfg.package;
- gnome = pkgs.gnome;
stdenv = pkgs.stdenv;
knownVideoDrivers = {
@@ -344,25 +302,9 @@ let
# Get a bunch of user settings.
videoDriver = cfg.videoDriver;
resolutions = map (res: ''"${toString res.x}x${toString res.y}"'') (cfg.resolutions);
- sessionType = cfg.sessionType;
videoDriverModules = getAttr [ videoDriver ] (throw "unkown video driver : \"${videoDriver}\"") knownVideoDrivers;
- sessionCmd =
- if sessionType == "" then cfg.sessionStarter else
- if sessionType == "xterm" then "${pkgs.xterm}/bin/xterm -ls" else
- if sessionType == "gnome" then "${gnome.gnometerminal}/bin/gnome-terminal -ls" else
- abort ("unknown session type ${sessionType}");
-
-
- windowManager =
- let wm = cfg.windowManager; in
- if wm != "" then wm else
- if sessionType == "gnome" then "metacity" else
- if sessionType == "kde" then "none" /* started by startkde */ else
- "twm";
-
-
modules =
getAttr ["modulesFirst"] [] videoDriverModules
@@ -518,240 +460,7 @@ let
};
- clientScript = pkgs.writeText "xclient" ''
-
- source /etc/profile
-
- exec > $HOME/.Xerrors 2>&1
-
-
- ### Load X defaults.
- if test -e ~/.Xdefaults; then
- ${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
- fi
-
-
- ${if cfg.startSSHAgent then ''
- ### Start the SSH agent.
- export SSH_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass
- eval $(${pkgs.openssh}/bin/ssh-agent)
- '' else ""}
-
- ### Allow user to override system-wide configuration
- if test -f ~/.xsession; then
- source ~/.xsession;
- fi
-
-
- ### Start a window manager.
-
- ${if windowManager == "twm" then ''
- ${xorg.twm}/bin/twm &
- ''
-
- else if windowManager == "metacity" then ''
- env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/
- # !!! Hack: load the schemas for Metacity.
- GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
- --makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */
- ${gnome.metacity}/bin/metacity &
- ''
-
- else if windowManager == "kwm" then ''
- ${pkgs.kdebase}/bin/kwin &
- ''
-
- else if windowManager == "compiz" then ''
- # !!! Hack: load the schemas for Compiz.
- GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
- --makefile-install-rule ${pkgs.compiz}/etc/gconf/schemas/*.schemas # */
-
- # !!! Hack: turn on most Compiz modules.
- ${gnome.GConf}/bin/gconftool-2 -t list --list-type=string \
- --set /apps/compiz/general/allscreens/options/active_plugins \
- [gconf,png,decoration,wobbly,fade,minimize,move,resize,cube,switcher,rotate,place,scale,water]
-
- # Start Compiz and the GTK-style window decorator.
- env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/
- ${pkgs.compiz}/bin/compiz gconf ${cfg.renderingFlag} &
- ${pkgs.compiz}/bin/gtk-window-decorator --sync &
- ''
-
- else if windowManager == "xmonad" then ''
- ${pkgs.xmonad}/bin/xmonad &
- ''
-
- else if windowManager == "none" then ''
- # The session starter will start the window manager.
- ''
-
- else abort ("unknown window manager " + windowManager)}
-
-
- ### Show a background image.
- # (but not if we're starting a full desktop environment that does it for us)
- ${if sessionType != "kde" then ''
-
- if test -e $HOME/.background-image; then
- ${pkgs.feh}/bin/feh --bg-scale $HOME/.background-image
- fi
-
- '' else ""}
-
-
- ### Start the session.
- ${if sessionType == "kde" then ''
-
- # Start KDE.
- export KDEDIRS=$HOME/.nix-profile:/nix/var/nix/profiles/default:${pkgs.kdebase}:${pkgs.kdelibs}
- export XDG_CONFIG_DIRS=${pkgs.kdebase}/etc/xdg:${pkgs.kdelibs}/etc/xdg
- export XDG_DATA_DIRS=${pkgs.kdebase}/share
- exec ${pkgs.kdebase}/bin/startkde
-
- '' else ''
-
- # For all other session types, we currently just start a
- # terminal of the kind indicated by sessionCmd.
- # !!! yes, this means that you 'log out' by killing the X server.
- while ${sessionCmd}; do
- sleep 1
- done
-
- ''}
-
- '';
-
-
- xserverArgs = [
- "-ac"
- "-logverbose"
- "-verbose"
- "-terminate"
- "-logfile" "/var/log/X.${toString cfg.display}.log"
- "-config ${configFile}"
- ":${toString cfg.display}" "vt${toString cfg.tty}"
- "-xkbdir" "${pkgs.xkeyboard_config}/etc/X11/xkb"
- ] ++ optional (!config.services.xserver.tcpEnable) "-nolisten tcp";
-
-
- slimConfig = pkgs.writeText "slim.cfg" ''
- xauth_path ${xorg.xauth}/bin/xauth
- default_xserver ${xorg.xorgserver}/bin/X
- xserver_arguments ${toString xserverArgs}
- login_cmd exec ${stdenv.bash}/bin/sh ${clientScript}
- halt_cmd ${pkgs.upstart}/sbin/shutdown -h now
- reboot_cmd ${pkgs.upstart}/sbin/shutdown -r now
- ${if cfg.slim.defaultUser != "" then "default_user " + cfg.slim.defaultUser else ""}
- ${if cfg.slim.hideCursor then "hidecursor true" else ""}
- '';
-
-
- # Unpack the SLiM theme, or use the default.
- slimThemesDir =
- let
- unpackedTheme = stdenv.mkDerivation {
- name = "slim-theme";
- buildCommand = ''
- ensureDir $out
- cd $out
- unpackFile ${cfg.slim.theme}
- ln -s * default
- '';
- };
- in if cfg.slim.theme == null then "${pkgs.slim}/share/slim/themes" else unpackedTheme;
-
- nvidiaDrivers = (config.boot.kernelPackages pkgs).nvidiaDrivers;
-
- oldJob = rec {
- # Warning the indentation is wrong since here in order to don't produce noise in diffs.
-
- name = "xserver";
-
-
- extraPath = [
- xorg.xrandr
- xorg.xrdb
- xorg.setxkbmap
- xorg.iceauth # required for KDE applications (it's called by dcopserver)
- pkgs.feh
- ]
- ++ optional (windowManager == "twm") [
- xorg.twm
- ]
- ++ optional (windowManager == "metacity") [
- gnome.metacity
- ]
- ++ optional (windowManager == "compiz") [
- pkgs.compiz
- ]
- ++ optional (sessionType == "xterm") [
- pkgs.xterm
- ]
- ++ optional (sessionType == "gnome") [
- gnome.gnometerminal
- gnome.GConf
- gnome.gconfeditor
- ]
- ++ optional (sessionType == "kde") [
- pkgs.kdelibs
- pkgs.kdebase
- xorg.xset # used by startkde, non-essential
- ]
- ++ optional (videoDriver == "nvidia") [
- kernelPackages.nvidiaDrivers
- ];
-
-
- extraEtc =
- optional (sessionType == "kde")
- { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
- target = "X11/xkb";
- }
- ++
- optional cfg.exportConfiguration
- { source = "${configFile}";
- target = "X11/xorg.conf";
- };
-
-
- job = ''
- start on ${if cfg.autorun then "network-interfaces" else "never"}
-
- start script
-
- rm -f /var/run/opengl-driver
- ${if videoDriver == "nvidia"
- then ''
- ln -sf ${kernelPackages.nvidiaDrivers} /var/run/opengl-driver
- ''
- else if cfg.driSupport
- then "ln -sf ${pkgs.mesa} /var/run/opengl-driver"
- else ""
- }
-
- rm -f /var/log/slim.log
-
- end script
-
- env SLIM_CFGFILE=${slimConfig}
- env SLIM_THEMESDIR=${slimThemesDir}
- env FONTCONFIG_FILE=/etc/fonts/fonts.conf # !!! cleanup
- env XKB_BINDIR=${xorg.xkbcomp}/bin # Needed for the Xkb extension.
-
- ${if videoDriver == "nvidia"
- then "env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidiaDrivers}/lib"
- else ""
- }
-
- ${if videoDriver != "nvidia"
- then "env XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/modules/dri"
- else ""
- }
-
- exec ${pkgs.slim}/bin/slim
- '';
-
-};
+ nvidiaDrivers = (config.boot.kernelPackages pkgs).nvidiaDrivers;
in
@@ -759,14 +468,19 @@ mkIf cfg.enable {
require = [
options
+ # services.xserver.*Manager
+ (import ./displayManager/default.nix)
+ (import ./windowManager/default.nix)
+ (import ./desktopManager/default.nix)
+
# services.extraJobs
- (import ../upstart-jobs/default.nix)
+ (import ../../upstart-jobs/default.nix)
# environment.etc
- (import ../etc/default.nix)
+ (import ../../etc/default.nix)
# fonts.fonts
- (import ../system/fonts.nix)
+ (import ../../system/fonts.nix)
# boot.extraModulePackages
# security.extraSetuidPrograms
@@ -779,29 +493,77 @@ mkIf cfg.enable {
];
};
- security = {
- extraSetuidPrograms = mkIf (cfg.sessionType == "kde") [
- "kcheckpass"
+ environment = {
+ etc = mkIf cfg.exportConfiguration [
+ { source = "${configFile}";
+ target = "X11/xorg.conf";
+ }
+ ];
+
+ extraPackages = [
+ xorg.xrandr
+ xorg.xrdb
+ xorg.setxkbmap
+ xorg.iceauth # required for KDE applications (it's called by dcopserver)
+ ]
+ ++ optional (videoDriver == "nvidia") [
+ kernelPackages.nvidiaDrivers
];
};
- environment = {
- etc = [
- { source = ../etc/pam.d/kde;
- target = "pam.d/kde";
- }
- { source = ../etc/pam.d/slim;
- target = "pam.d/slim";
- }
- ] ++ oldJob.extraEtc;
-
- extraPackages =
- oldJob.extraPath;
- };
-
services = {
+ xserver = {
+ displayManager = {
+ xserverArgs = [
+ "-ac"
+ "-logverbose"
+ "-verbose"
+ "-terminate"
+ "-logfile" "/var/log/X.${toString cfg.display}.log"
+ "-config ${configFile}"
+ ":${toString cfg.display}" "vt${toString cfg.tty}"
+ "-xkbdir" "${pkgs.xkeyboard_config}/etc/X11/xkb"
+ ] ++ optional (!cfg.tcpEnable) "-nolisten tcp";
+ };
+ };
+
extraJobs = [{
- inherit (oldJob) name job;
+ name = "xserver";
+ job = ''
+ start on ${if cfg.autorun then "network-interfaces" else "never"}
+
+ start script
+
+ rm -f /var/run/opengl-driver
+ ${if videoDriver == "nvidia"
+ then ''
+ ln -sf ${kernelPackages.nvidiaDrivers} /var/run/opengl-driver
+ ''
+ else if cfg.driSupport
+ then "ln -sf ${pkgs.mesa} /var/run/opengl-driver"
+ else ""
+ }
+
+ ${cfg.displayManager.job.beforeScript}
+
+ end script
+
+ ${cfg.displayManager.job.env}
+ env FONTCONFIG_FILE=/etc/fonts/fonts.conf # !!! cleanup
+ env XKB_BINDIR=${xorg.xkbcomp}/bin # Needed for the Xkb extension.
+
+ ${if videoDriver == "nvidia"
+ then "env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidiaDrivers}/lib"
+ else ""
+ }
+
+ ${if videoDriver != "nvidia"
+ then "env XORG_DRI_DRIVER_PATH=${pkgs.mesa}/lib/modules/dri"
+ else ""
+ }
+
+ exec ${cfg.displayManager.job.execCmd}
+ '';
}];
};
}
diff --git a/upstart-jobs/xserver/desktopManager/default.nix b/upstart-jobs/xserver/desktopManager/default.nix
new file mode 100644
index 00000000000..ab1271e69ae
--- /dev/null
+++ b/upstart-jobs/xserver/desktopManager/default.nix
@@ -0,0 +1,73 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mergeOneOption mkIf filter optionalString any;
+ cfg = config.services.xserver.desktopManager;
+
+ needBGCond = d: ! (d ? bgSupport && d.bgSupport);
+in
+
+{
+ require = [
+ (import ./kde.nix)
+ (import ./gnome.nix)
+ (import ./xterm.nix)
+ (import ./none.nix)
+ ];
+
+ services = {
+ xserver = {
+ displayManager = {
+ session = cfg.session.list;
+ };
+
+ desktopManager = {
+ session = mkOption {
+ default = [];
+ example = [{
+ name = "kde";
+ bgSupport = true;
+ start = "...";
+ }];
+ description = "
+ Internal option used to add some common line to desktop manager
+ scripts before forwarding the value to the
+ displayManager.
+ ";
+ apply = list: {
+ list = map (d: d // {
+ manage = "desktop";
+ start = d.start
+ + optionalString (needBGCond d) ''
+ if test -e $HOME/.background-image; then
+ ${pkgs.feh}/bin/feh --bg-scale $HOME/.background-image
+ fi
+ '';
+ }) list;
+ needBGPackages = [] != filter needBGCond list;
+ };
+ };
+
+
+
+ default = mkOption {
+ default = "xterm";
+ example = "none";
+ description = "
+ Default desktop manager loaded if none have been chosen.
+ ";
+ merge = list:
+ let defaultDM = mergeOneOption list; in
+ if any (w: w.name == defaultDM) cfg.session.list then
+ defaultDM
+ else
+ throw "Default desktop manager not found.";
+ };
+ };
+ };
+ };
+
+ environment = mkIf cfg.session.needBGPackages {
+ extraPackages = [ pkgs.feh ];
+ };
+}
diff --git a/upstart-jobs/xserver/desktopManager/gnome.nix b/upstart-jobs/xserver/desktopManager/gnome.nix
new file mode 100644
index 00000000000..d6fa064ef11
--- /dev/null
+++ b/upstart-jobs/xserver/desktopManager/gnome.nix
@@ -0,0 +1,47 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.desktopManager.gnome;
+ gnome = pkgs.gnome;
+
+ options = { services = { xserver = { desktopManager = {
+
+ gnome = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable a gnome terminal as a desktop manager.";
+ };
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = options;
+
+ services = {
+ xserver = {
+
+ desktopManager = {
+ session = [{
+ name = "gnome";
+ start = ''
+ ${gnome.gnometerminal}/bin/gnome-terminal -ls &
+ waitPID=$!
+ '';
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [
+ gnome.gnometerminal
+ gnome.GConf
+ gnome.gconfeditor
+ ];
+ };
+}
diff --git a/upstart-jobs/xserver/desktopManager/kde.nix b/upstart-jobs/xserver/desktopManager/kde.nix
new file mode 100644
index 00000000000..9a241d77985
--- /dev/null
+++ b/upstart-jobs/xserver/desktopManager/kde.nix
@@ -0,0 +1,65 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.desktopManager.kde;
+ xorg = config.services.xserver.package;
+
+ options = { services = { xserver = { desktopManager = {
+
+ kde = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the kde desktop manager.";
+ };
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = options;
+
+ services = {
+ xserver = {
+
+ desktopManager = {
+ session = [{
+ name = "kde";
+ start = ''
+ # Start KDE.
+ export KDEDIRS=$HOME/.nix-profile:/nix/var/nix/profiles/default:${pkgs.kdebase}:${pkgs.kdelibs}
+ export XDG_CONFIG_DIRS=${pkgs.kdebase}/etc/xdg:${pkgs.kdelibs}/etc/xdg
+ export XDG_DATA_DIRS=${pkgs.kdebase}/share
+ exec ${pkgs.kdebase}/bin/startkde
+ '';
+ }];
+ };
+
+ };
+ };
+
+ security = {
+ extraSetuidPrograms = [
+ "kcheckpass"
+ ];
+ };
+
+ environment = {
+ extraPackages = [
+ pkgs.kdelibs
+ pkgs.kdebase
+ xorg.xset # used by startkde, non-essential
+ ];
+
+ etc = [
+ { source = ../../../etc/pam.d/kde;
+ target = "pam.d/kde";
+ }
+ { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
+ target = "X11/xkb";
+ }
+ ];
+ };
+}
diff --git a/upstart-jobs/xserver/desktopManager/none.nix b/upstart-jobs/xserver/desktopManager/none.nix
new file mode 100644
index 00000000000..a86bd5a7415
--- /dev/null
+++ b/upstart-jobs/xserver/desktopManager/none.nix
@@ -0,0 +1,14 @@
+{
+ services = {
+ xserver = {
+
+ desktopManager = {
+ session = [{
+ name = "none";
+ start = "";
+ }];
+ };
+
+ };
+ };
+}
diff --git a/upstart-jobs/xserver/desktopManager/xterm.nix b/upstart-jobs/xserver/desktopManager/xterm.nix
new file mode 100644
index 00000000000..e8aa0d289cb
--- /dev/null
+++ b/upstart-jobs/xserver/desktopManager/xterm.nix
@@ -0,0 +1,44 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.desktopManager.xterm;
+
+ options = { services = { xserver = { desktopManager = {
+
+ xterm = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable a xterm terminal as a desktop manager.";
+ };
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = options;
+
+ services = {
+ xserver = {
+
+ desktopManager = {
+ session = [{
+ name = "xterm";
+ start = ''
+ ${pkgs.xterm}/bin/xterm -ls &
+ waitPID=$!
+ '';
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [
+ pkgs.xterm
+ ];
+ };
+}
diff --git a/upstart-jobs/xserver/displayManager/default.nix b/upstart-jobs/xserver/displayManager/default.nix
new file mode 100644
index 00000000000..12393af8f6c
--- /dev/null
+++ b/upstart-jobs/xserver/displayManager/default.nix
@@ -0,0 +1,167 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mergeOneOption optionals filter concatMap concatMapStrings;
+ cfg = config.services.xserver;
+ xorg = cfg.package;
+
+ # file provided by services.xserver.displayManager.session.script
+ xsession = wm: dm: pkgs.writeText "xsession" ''
+
+ source /etc/profile
+
+ exec > $HOME/.Xerrors 2>&1
+
+
+ ### Load X defaults.
+ if test -e ~/.Xdefaults; then
+ ${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
+ fi
+
+ ${if cfg.startSSHAgent then ''
+ ### Start the SSH agent.
+ export SSH_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass
+ eval $(${pkgs.openssh}/bin/ssh-agent)
+ '' else ""}
+
+ ### Allow user to override system-wide configuration
+ if test -f ~/.xsession; then
+ source ~/.xsession;
+ fi
+
+ # this script expect to have as first argument the following input
+ # "desktop-manager + window-manager".
+ arg="$1"
+
+ # extract the window manager.
+ windowManager="''${arg##* + }"
+ : ''${windowManager:=${cfg.windowManager.default}}
+ # extract the desktop manager.
+ desktopManager="''${arg% + *}"
+ : ''${desktopManager:=${cfg.desktopManager.default}}
+
+ # used to restart the xserver.
+ waitPID=0
+
+ # handle window manager starts.
+ case $windowManager in
+ ${concatMapStrings (s: "
+ (${s.name})
+ ${s.start}
+ ;;
+ ") wm}
+ (*) echo "$0: Window manager '$windowManager' not found.";;
+ esac
+
+ # handle desktop manager starts.
+ case $desktopManager in
+ ${concatMapStrings (s: "
+ (${s.name})
+ ${s.start}
+ ;;
+ ") dm}
+ (*) echo "$0: Desktop manager '$desktopManager' not found.";;
+ esac
+
+ test "$waitPID" != 0 && wait "$waitPID"
+ exit
+ '';
+
+in
+
+{
+ # list of display managers.
+ require = [
+ (import ./slim.nix)
+ ];
+
+ services = {
+ xserver = {
+ displayManager = {
+
+ xauthBin = mkOption {
+ default = "${xorg.xauth}/bin/xauth";
+ description = "
+ Path to the xauth binary used by display managers.
+ ";
+ };
+
+ xserverBin = mkOption {
+ default = "${xorg.xorgserver}/bin/X";
+ description = "
+ Path to the xserver binary used by display managers.
+ ";
+ };
+
+ xserverArgs = mkOption {
+ default = [];
+ example = [
+ "-ac"
+ "-logverbose"
+ "-nolisten tcp"
+ ];
+ description = "
+ List of arguments which have to be pass to when
+ the display manager start the xserver.
+ ";
+ apply = toString;
+ };
+
+ session = mkOption {
+ default = [];
+ example = [
+ {
+ manage = "desktop";
+ name = "xterm";
+ start = "
+ ${pkgs.xterm}/bin/xterm -ls &
+ waitPID=$!
+ ";
+ }
+ ];
+ description = ''
+ List of session supported with the command used to start each
+ session. Each session script can set the
+ waitPID shell variable to make this script
+ waiting until the end of the user session. Each script is used
+ to define either a windows manager or a desktop manager. These
+ can be differentiated by setting the attribute
+ manage either to "window"
+ or "desktop".
+
+ The list of desktop manager and window manager should appear
+ inside the display manager with the desktop manager name
+ followed by the window manager name.
+ '';
+ apply = list: rec {
+ wm = filter (s: s.manage == "window") list;
+ dm = filter (s: s.manage == "desktop") list;
+ names = concatMap (d: map (w: d.name + " + " + w.name) wm) dm;
+ script = xsession wm dm;
+ };
+ };
+
+ job = mkOption {
+ default = {};
+ example = {
+ beforeScript = ''
+ rm -f /var/log/slim.log
+ '';
+ env = ''
+ env SLIM_CFGFILE=/etc/slim.conf
+ '';
+ execCmd = "${pkgs.slim}/bin/slim";
+ };
+
+ description = "
+ List of arguments which have to be pass to when
+ the display manager start the xserver.
+ ";
+
+ merge = mergeOneOption;
+ };
+
+ };
+ };
+ };
+}
diff --git a/upstart-jobs/xserver/displayManager/slim.nix b/upstart-jobs/xserver/displayManager/slim.nix
new file mode 100644
index 00000000000..8363a7a14ee
--- /dev/null
+++ b/upstart-jobs/xserver/displayManager/slim.nix
@@ -0,0 +1,112 @@
+{pkgs, config, ...}:
+
+###### interface
+let
+ inherit (pkgs.lib) mkOption;
+
+ options = { services = { xserver = {
+
+ slim = {
+
+ theme = mkOption {
+ default = null;
+ example = pkgs.fetchurl {
+ url = http://download.berlios.de/slim/slim-wave.tar.gz;
+ sha256 = "0ndr419i5myzcylvxb89m9grl2xyq6fbnyc3lkd711mzlmnnfxdy";
+ };
+ description = "
+ The theme for the SLiM login manager. If not specified, SLiM's
+ default theme is used. See for a
+ collection of themes.
+ ";
+ };
+
+ defaultUser = mkOption {
+ default = "";
+ example = "login";
+ description = "
+ The default user to load. If you put a username here you
+ get it automatically loaded into the username field, and
+ the focus is placed on the password.
+ ";
+ };
+
+ hideCursor = mkOption {
+ default = false;
+ example = true;
+ description = "
+ Hide the mouse cursor on the login screen.
+ ";
+ };
+ };
+
+ }; /* xserver */ }; /* services */ };
+
+in
+
+###### implementation
+let
+ xcfg = config.services.xserver;
+ dmcfg = xcfg.displayManager;
+ cfg = xcfg.slim;
+
+ slimConfig = pkgs.writeText "slim.cfg" ''
+ xauth_path ${dmcfg.xauthBin}
+ default_xserver ${dmcfg.xserverBin}
+ xserver_arguments ${dmcfg.xserverArgs}
+ sessions ${pkgs.lib.concatStringsSep "," dmcfg.session.names}
+ login_cmd exec ${pkgs.stdenv.bash}/bin/sh ${dmcfg.session.script} "%session"
+ halt_cmd ${pkgs.upstart}/sbin/shutdown -h now
+ reboot_cmd ${pkgs.upstart}/sbin/shutdown -r now
+ ${if cfg.defaultUser != "" then "default_user " + cfg.defaultUser else ""}
+ ${if cfg.hideCursor then "hidecursor true" else ""}
+ '';
+
+
+ # Unpack the SLiM theme, or use the default.
+ slimThemesDir =
+ let
+ unpackedTheme = pkgs.stdenv.mkDerivation {
+ name = "slim-theme";
+ buildCommand = ''
+ ensureDir $out
+ cd $out
+ unpackFile ${cfg.theme}
+ ln -s * default
+ '';
+ };
+ in if cfg.theme == null then "${pkgs.slim}/share/slim/themes" else unpackedTheme;
+
+in
+
+{
+ require = [
+ options
+ ];
+
+ services = {
+ xserver = {
+ displayManager = {
+ job = {
+ beforeScript = ''
+ rm -f /var/log/slim.log
+ '';
+ env = ''
+ env SLIM_CFGFILE=${slimConfig}
+ env SLIM_THEMESDIR=${slimThemesDir}
+ '';
+ execCmd = "${pkgs.slim}/bin/slim";
+ };
+ };
+ };
+ };
+
+ environment = {
+ etc = [
+ { source = ../../../etc/pam.d/slim;
+ target = "pam.d/slim";
+ }
+ ];
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/compiz.nix b/upstart-jobs/xserver/windowManager/compiz.nix
new file mode 100644
index 00000000000..e99c3adb5b4
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/compiz.nix
@@ -0,0 +1,64 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.compiz;
+ xorg = config.services.xserver.package;
+ gnome = pkgs.gnome;
+
+ options = { services = { xserver = { windowManager = {
+
+ compiz = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the compiz window manager.";
+ };
+
+
+ renderingFlag = mkOption {
+ default = "";
+ example = "--indirect-rendering";
+ description = "
+ Possibly pass --indierct-rendering to Compiz.
+ ";
+ };
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = options;
+
+ services = {
+ xserver = {
+
+ windowManager = {
+ session = [{
+ name = "compiz";
+ start = ''
+ # !!! Hack: load the schemas for Compiz.
+ GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
+ --makefile-install-rule ${pkgs.compiz}/etc/gconf/schemas/*.schemas # */
+
+ # !!! Hack: turn on most Compiz modules.
+ ${gnome.GConf}/bin/gconftool-2 -t list --list-type=string \
+ --set /apps/compiz/general/allscreens/options/active_plugins \
+ [gconf,png,decoration,wobbly,fade,minimize,move,resize,cube,switcher,rotate,place,scale,water]
+
+ # Start Compiz and the GTK-style window decorator.
+ env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/
+ ${pkgs.compiz}/bin/compiz gconf ${cfg.renderingFlag} &
+ ${pkgs.compiz}/bin/gtk-window-decorator --sync &
+ '';
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [ pkgs.compiz ];
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/default.nix b/upstart-jobs/xserver/windowManager/default.nix
new file mode 100644
index 00000000000..cb5a1b674e0
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/default.nix
@@ -0,0 +1,58 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mergeOneOption any;
+ cfg = config.services.xserver.windowManager;
+in
+
+{
+ require = [
+ (import ./compiz.nix)
+ (import ./kwm.nix)
+ (import ./metacity.nix)
+ (import ./none.nix)
+ (import ./twm.nix)
+ (import ./wmii.nix)
+ (import ./xmonad.nix)
+ ];
+
+ services = {
+ xserver = {
+ displayManager = {
+ session = cfg.session;
+ };
+
+ windowManager = {
+ session = mkOption {
+ default = [];
+ example = [{
+ name = "wmii";
+ start = "...";
+ }];
+ description = "
+ Internal option used to add some common line to window manager
+ scripts before forwarding the value to the
+ displayManager.
+ ";
+ apply = map (d: d // {
+ manage = "window";
+ });
+ };
+
+ default = mkOption {
+ default = "none";
+ example = "wmii";
+ description = "
+ Default window manager loaded if none have been chosen.
+ ";
+ merge = list:
+ let defaultWM = mergeOneOption list; in
+ if any (w: w.name == defaultWM) cfg.session then
+ defaultWM
+ else
+ throw "Default window manager not found.";
+ };
+ };
+ };
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/kwm.nix b/upstart-jobs/xserver/windowManager/kwm.nix
new file mode 100644
index 00000000000..db8696c510d
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/kwm.nix
@@ -0,0 +1,46 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.kwm;
+
+ option = { services = { xserver = { windowManager = {
+
+ kwm = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the kwm window manager.";
+ };
+
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = option;
+
+ services = {
+ xserver = {
+
+ windowManager = {
+ session = [{
+ name = "kwm";
+ start = "
+ ${pkgs.kdebase}/bin/kwin &
+ waitPID=$!
+ ";
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [
+ pkgs.kdelibs
+ pkgs.kdebase
+ ];
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/metacity.nix b/upstart-jobs/xserver/windowManager/metacity.nix
new file mode 100644
index 00000000000..dc1ff911d65
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/metacity.nix
@@ -0,0 +1,49 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.metacity;
+ xorg = config.services.xserver.package;
+ gnome = pkgs.gnome;
+
+ option = { services = { xserver = { windowManager = {
+
+ metacity = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the metacity window manager.";
+ };
+
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = option;
+
+ services = {
+ xserver = {
+
+ windowManager = {
+ session = [{
+ name = "metacity";
+ start = ''
+ env LD_LIBRARY_PATH=${xorg.libX11}/lib:${xorg.libXext}/lib:/usr/lib/
+ # !!! Hack: load the schemas for Metacity.
+ GCONF_CONFIG_SOURCE=xml::~/.gconf ${gnome.GConf}/bin/gconftool-2 \
+ --makefile-install-rule ${gnome.metacity}/etc/gconf/schemas/*.schemas # */
+ ${gnome.metacity}/bin/metacity &
+ waitPID=$!
+ '';
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [ gnome.metacity ];
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/none.nix b/upstart-jobs/xserver/windowManager/none.nix
new file mode 100644
index 00000000000..84cf1d77077
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/none.nix
@@ -0,0 +1,12 @@
+{
+ services = {
+ xserver = {
+ windowManager = {
+ session = [{
+ name = "none";
+ start = "";
+ }];
+ };
+ };
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/twm.nix b/upstart-jobs/xserver/windowManager/twm.nix
new file mode 100644
index 00000000000..f26be48776c
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/twm.nix
@@ -0,0 +1,44 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.twm;
+ xorg = config.services.xserver.package;
+
+ option = { services = { xserver = { windowManager = {
+
+ twm = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the twm window manager.";
+ };
+
+ };
+
+ }; }; }; };
+in
+
+mkIf cfg.enable {
+ require = option;
+
+ services = {
+ xserver = {
+
+ windowManager = {
+ session = [{
+ name = "twm";
+ start = "
+ ${xorg.twm}/bin/twm &
+ waitPID=$!
+ ";
+ }];
+ };
+
+ };
+ };
+
+ environment = {
+ extraPackages = [ xorg.twm ];
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/wmii.nix b/upstart-jobs/xserver/windowManager/wmii.nix
new file mode 100644
index 00000000000..59a88f9352f
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/wmii.nix
@@ -0,0 +1,32 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.wmii;
+in
+
+{
+ services = {
+ xserver = {
+
+ windowManager = {
+ wmii = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the wmii window manager.";
+ };
+ };
+
+ session = mkIf cfg.enable [{
+ name = "wmii";
+ start = "
+ ${pkgs.wmiiSnap}/bin/wmii &
+ waitPID=$!
+ ";
+ }];
+ };
+
+ };
+ };
+}
diff --git a/upstart-jobs/xserver/windowManager/xmonad.nix b/upstart-jobs/xserver/windowManager/xmonad.nix
new file mode 100644
index 00000000000..6f73ad9edc3
--- /dev/null
+++ b/upstart-jobs/xserver/windowManager/xmonad.nix
@@ -0,0 +1,32 @@
+{pkgs, config, ...}:
+
+let
+ inherit (pkgs.lib) mkOption mkIf;
+ cfg = config.services.xserver.windowManager.xmonad;
+in
+
+{
+ services = {
+ xserver = {
+
+ windowManager = {
+ xmonad = {
+ enable = mkOption {
+ default = false;
+ example = true;
+ description = "Enable the xmonad window manager.";
+ };
+ };
+
+ session = mkIf cfg.enable [{
+ name = "xmonad";
+ start = "
+ ${pkgs.xmonad}/bin/xmonad &
+ waitPID=$!
+ ";
+ }];
+ };
+
+ };
+ };
+}
diff --git a/upstart-jobs/xserver.conf b/upstart-jobs/xserver/xserver.conf
similarity index 100%
rename from upstart-jobs/xserver.conf
rename to upstart-jobs/xserver/xserver.conf
diff --git a/upstart-jobs/zabbix-agent.nix b/upstart-jobs/zabbix-agent.nix
index cb3895f81f1..55a71619dcc 100644
--- a/upstart-jobs/zabbix-agent.nix
+++ b/upstart-jobs/zabbix-agent.nix
@@ -1,5 +1,5 @@
# Zabbix agent daemon.
-{config, pkgs}:
+{config, pkgs, ...}:
###### interface
let
diff --git a/upstart-jobs/zabbix-server.nix b/upstart-jobs/zabbix-server.nix
index 07a31e7d7d7..e683b31ae61 100644
--- a/upstart-jobs/zabbix-server.nix
+++ b/upstart-jobs/zabbix-server.nix
@@ -1,5 +1,5 @@
# Zabbix server daemon.
-{config, pkgs}:
+{config, pkgs, ...}:
###### interface
let