about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/config/timezone.nix6
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix4
-rw-r--r--nixos/modules/rename.nix5
-rw-r--r--nixos/modules/services/databases/postgresql.nix6
-rw-r--r--nixos/modules/services/misc/cgminer.nix17
-rw-r--r--nixos/modules/services/networking/connman.nix94
-rw-r--r--nixos/modules/services/networking/kippo.nix115
-rw-r--r--nixos/modules/services/networking/networkmanager.nix5
-rw-r--r--nixos/modules/services/ttys/kmscon.nix74
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix1
-rw-r--r--nixos/modules/services/x11/mesa.nix117
-rw-r--r--nixos/modules/services/x11/xserver.nix117
-rw-r--r--nixos/modules/system/boot/loader/gummiboot/gummiboot.nix2
-rw-r--r--nixos/modules/system/boot/systemd.nix20
-rw-r--r--nixos/modules/system/etc/setup-etc.pl10
16 files changed, 463 insertions, 132 deletions
diff --git a/nixos/modules/config/timezone.nix b/nixos/modules/config/timezone.nix
index 07a76d9ad1fa..42fbe841d070 100644
--- a/nixos/modules/config/timezone.nix
+++ b/nixos/modules/config/timezone.nix
@@ -25,9 +25,11 @@ with pkgs.lib;
   config = {
 
     environment.variables.TZDIR = "/etc/zoneinfo";
-    environment.variables.TZ = config.time.timeZone;
 
-    environment.etc.localtime.source = "${pkgs.tzdata}/share/zoneinfo/${config.time.timeZone}";
+    environment.etc.localtime =
+      { source = "${pkgs.tzdata}/share/zoneinfo/${config.time.timeZone}";
+        mode = "direct-symlink";
+      };
 
     environment.etc.zoneinfo.source = "${pkgs.tzdata}/share/zoneinfo";
 
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 6f2666e4ae54..16eec9043212 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -109,6 +109,7 @@
       mongodb = 98;
       openldap = 99;
       memcached = 100;
+      cgminer = 101;
 
       # When adding a uid, make sure it doesn't match an existing gid.
 
@@ -197,6 +198,7 @@
       minidlna = 91;
       haproxy = 92;
       openldap = 93;
+      connman = 94;
 
       # When adding a gid, make sure it doesn't match an existing uid.
 
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 684850df2aec..86a3dca0d1e2 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -147,6 +147,7 @@
   ./services/networking/avahi-daemon.nix
   ./services/networking/bind.nix
   ./services/networking/bitlbee.nix
+  ./services/networking/connman.nix
   ./services/networking/cntlm.nix
   ./services/networking/chrony.nix
   ./services/networking/ddclient.nix
@@ -167,6 +168,7 @@
   ./services/networking/ifplugd.nix
   ./services/networking/iodined.nix
   ./services/networking/ircd-hybrid/default.nix
+  ./services/networking/kippo.nix
   ./services/networking/minidlna.nix
   ./services/networking/nat.nix
   ./services/networking/networkmanager.nix
@@ -212,6 +214,7 @@
   ./services/torrent/transmission.nix
   ./services/ttys/gpm.nix
   ./services/ttys/agetty.nix
+  ./services/ttys/kmscon.nix
   ./services/web-servers/apache-httpd/default.nix
   ./services/web-servers/jboss/default.nix
   ./services/web-servers/lighttpd/default.nix
@@ -230,6 +233,7 @@
   ./services/x11/hardware/multitouch.nix
   ./services/x11/hardware/synaptics.nix
   ./services/x11/hardware/wacom.nix
+  ./services/x11/mesa.nix
   ./services/x11/window-managers/awesome.nix
   #./services/x11/window-managers/compiz.nix
   ./services/x11/window-managers/default.nix
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index ae3c9faeea68..6ff5277cf9ca 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -113,6 +113,11 @@ in zipModules ([]
 # !!! this hardcodes bash, could we detect from config which shell is actually used?
 ++ obsolete [ "environment" "promptInit" ] [ "programs" "bash" "promptInit" ]
 
+++ obsolete [ "services" "xserver" "driSupport" ] [ "services" "mesa" "driSupport" ]
+++ obsolete [ "services" "xserver" "driSupport32Bit" ] [ "services" "mesa" "driSupport32Bit" ]
+++ obsolete [ "services" "xserver" "s3tcSupport" ] [ "services" "mesa" "s3tcSupport" ]
+++ obsolete [ "services" "xserver" "videoDrivers" ] [ "services" "mesa" "videoDrivers" ]
+
 # Options that are obsolete and have no replacement.
 ++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
 ++ obsolete' [ "boot" "initrd" "luks" "enable" ]
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 1563858887e6..265d26e8ce98 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -82,7 +82,11 @@ in
         type = types.lines;
         default = "";
         description = ''
-          Defines how users authenticate themselves to the server.
+          Defines how users authenticate themselves to the server. By
+          default, "trust" access to local users will always be granted
+          along with any other custom options. If you do not want this,
+          set this option using "pkgs.lib.mkForce" to override this
+          behaviour.
         '';
       };
 
diff --git a/nixos/modules/services/misc/cgminer.nix b/nixos/modules/services/misc/cgminer.nix
index 890d7a4020bc..f715013b51f3 100644
--- a/nixos/modules/services/misc/cgminer.nix
+++ b/nixos/modules/services/misc/cgminer.nix
@@ -108,20 +108,21 @@ in
 
   config = mkIf config.services.cgminer.enable {
 
-    users.extraUsers = singleton
-      { name = cfg.user;
+    users.extraUsers = optionalAttrs (cfg.user == "cgminer") (singleton
+      { name = "cgminer";
+        uid = config.ids.uids.cgminer;
         description = "Cgminer user";
-      };
+      });
 
     environment.systemPackages = [ cfg.package ];
 
     systemd.services.cgminer = {
       path = [ pkgs.cgminer ];
 
-      after = [ "display-manager.target" "network.target" ];
+      after = [ "network.target" "display-manager.service" ];
       wantedBy = [ "multi-user.target" ];
 
-      environment = { 
+      environment = {
         LD_LIBRARY_PATH = ''/run/opengl-driver/lib:/run/opengl-driver-32/lib'';
         DISPLAY = ":0";
         GPU_MAX_ALLOC_PERCENT = "100";
@@ -129,9 +130,11 @@ in
       };
 
       serviceConfig = {
-        ExecStart = "${pkgs.cgminer}/bin/cgminer -T -c ${cgminerConfig}";
+        ExecStart = "${pkgs.cgminer}/bin/cgminer --syslog --text-only --config ${cgminerConfig}";
         User = cfg.user;
-        RestartSec = 10;
+        RestartSec = "30s";
+        Restart = "always";
+        StartLimitInterval = "1m";
       };
     };
 
diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix
new file mode 100644
index 000000000000..2b26fe88129b
--- /dev/null
+++ b/nixos/modules/services/networking/connman.nix
@@ -0,0 +1,94 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+with pkgs;
+
+let
+  cfg = config.networking.connman;
+
+in {
+
+  ###### interface
+
+  options = {
+
+    networking.connman = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to use ConnMan for managing your network connections.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    assertions = [{
+      assertion = config.networking.useDHCP == false;
+      message = "You can not use services.networking.connman with services.networking.useDHCP";
+    }{
+      assertion = config.networking.wireless.enable == true;
+      message = "You must use services.networking.connman with services.networking.wireless";
+    }{
+      assertion = config.networking.networkmanager.enable == false;
+      message = "You can not use services.networking.connman with services.networking.networkmanager";
+    }];
+
+    environment.systemPackages = [ connman ];
+
+    systemd.services."connman" = {
+      description = "Connection service";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "syslog.target" ];
+      serviceConfig = {
+        Type = "dbus";
+        BusName = "net.connman";
+        Restart = "on-failure";
+        ExecStart = "${pkgs.connman}/sbin/connmand --nodaemon";
+        StandardOutput = "null";
+      };
+    };
+
+    systemd.services."connman-vpn" = {
+      description = "ConnMan VPN service";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "syslog.target" ];
+      before = [ "connman" ];
+      serviceConfig = {
+        Type = "dbus";
+        BusName = "net.connman.vpn";
+        ExecStart = "${pkgs.connman}/sbin/connman-vpnd -n";
+        StandardOutput = "null";
+      };
+    };
+
+    systemd.services."net-connman-vpn" = {
+      description = "D-BUS Service";
+      serviceConfig = {
+        Name = "net.connman.vpn";
+        before = [ "connman" ];
+        ExecStart = "${pkgs.connman}/sbin/connman-vpnd -n";
+        User = "root";
+        SystemdService = "connman-vpn.service";
+      };
+    };
+
+    networking = {
+      useDHCP = false;
+      wireless.enable = true;
+      networkmanager.enable = false;
+    };
+
+    powerManagement.resumeCommands = ''
+      systemctl restart connman
+    '';
+
+  };
+}
diff --git a/nixos/modules/services/networking/kippo.nix b/nixos/modules/services/networking/kippo.nix
new file mode 100644
index 000000000000..76dd66013ba7
--- /dev/null
+++ b/nixos/modules/services/networking/kippo.nix
@@ -0,0 +1,115 @@
+# NixOS module for kippo honeypot ssh server
+# See all the options for configuration details.
+#
+# Default port is 2222. Recommend using something like this for port redirection to default SSH port:
+# networking.firewall.extraCommands = ''
+#      iptables -t nat -A PREROUTING -i IN_IFACE -p tcp --dport 22 -j REDIRECT --to-port 2222'';
+#
+# Lastly: use this service at your own risk. I am working on a way to run this inside a VM.
+{ pkgs, config, ... }:
+with pkgs.lib;
+let
+  cfg = config.services.kippo;
+in
+rec {
+  options = {
+    services.kippo = {
+      enable = mkOption {
+        default = false;
+        type = types.uniq types.bool;
+        description = ''Enable the kippo honeypot ssh server.'';
+      };
+      port = mkOption {
+        default = 2222;
+        type = types.uniq types.int;
+        description = ''TCP port number for kippo to bind to.'';
+      };
+      hostname = mkOption {
+        default = "nas3";
+        type = types.string;
+        description = ''Hostname for kippo to present to SSH login'';
+      };
+      varPath = mkOption {
+        default = "/var/lib/kippo";
+        type = types.string;
+        description = ''Path of read/write files needed for operation and configuration.'';
+      };
+      logPath = mkOption {
+        default = "/var/log/kippo";
+        type = types.string;
+        description = ''Path of log files needed for operation and configuration.'';
+      };
+      pidPath = mkOption {
+        default = "/run/kippo";
+        type = types.string;
+        description = ''Path of pid files needed for operation.'';
+      };
+      extraConfig = mkOption {
+        default = "";
+        type = types.string;
+        description = ''Extra verbatim configuration added to the end of kippo.cfg.'';
+      };
+    };
+
+  };
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs.pythonPackages; [
+      python twisted pycrypto pyasn1 ];
+
+    environment.etc."kippo.cfg".text = ''
+        # Automatically generated by NixOS.
+        # See ${pkgs.kippo}/src/kippo.cfg for details.
+        [honeypot]
+        log_path = ${cfg.logPath}
+        download_path = ${cfg.logPath}/dl
+        filesystem_file = ${cfg.varPath}/honeyfs
+        filesystem_file = ${cfg.varPath}/fs.pickle
+        data_path = ${cfg.varPath}/data
+        txtcmds_path = ${cfg.varPath}/txtcmds
+        public_key = ${cfg.varPath}/keys/public.key
+        private_key = ${cfg.varPath}/keys/private.key
+        ssh_port = ${toString cfg.port}
+        hostname = ${cfg.hostname}
+        ${cfg.extraConfig}
+    '';
+
+    users.extraUsers = singleton {
+      name = "kippo";
+      description = "kippo web server privilege separation user";
+    };
+    users.extraGroups = singleton { name = "kippo"; };
+
+    systemd.services.kippo = with pkgs; {
+      description = "Kippo Web Server";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      environment.PYTHONPATH = "${pkgs.kippo}/src/:${pkgs.pythonPackages.pycrypto}/lib/python2.7/site-packages/:${pkgs.pythonPackages.pyasn1}/lib/python2.7/site-packages/:${pkgs.pythonPackages.python}/lib/python2.7/site-packages/:${pkgs.pythonPackages.twisted}/lib/python2.7/site-packages/:.";
+      preStart = ''
+        if [ ! -d ${cfg.varPath}/ ] ; then 
+            mkdir -p ${cfg.pidPath}
+            mkdir -p ${cfg.logPath}/tty
+            mkdir -p ${cfg.logPath}/dl
+            mkdir -p ${cfg.varPath}/keys
+            cp ${pkgs.kippo}/src/honeyfs ${cfg.varPath} -r
+            cp ${pkgs.kippo}/src/fs.pickle ${cfg.varPath}/fs.pickle
+            cp ${pkgs.kippo}/src/data ${cfg.varPath} -r
+            cp ${pkgs.kippo}/src/txtcmds ${cfg.varPath} -r
+
+            chmod u+rw ${cfg.varPath} -R
+            chmod u+rw ${cfg.pidPath}
+            chown kippo.kippo ${cfg.varPath} -R
+            chown kippo.kippo ${cfg.pidPath}
+            chown kippo.kippo ${cfg.logPath} -R
+            chmod u+rw ${cfg.logPath} -R
+        fi
+      '';
+
+      serviceConfig.ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd -y ${pkgs.kippo}/src/kippo.tac --syslog --rundir=${cfg.varPath}/ --pidfile=${cfg.pidPath}/kippo.pid --prefix=kippo -n";
+      serviceConfig.PermissionsStartOnly = true;
+      serviceConfig.User = "kippo"; 
+      serviceConfig.Group = "kippo"; 
+    };
+};
+}
+
+
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 62bf38e4e708..40c20aae4ef0 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -146,6 +146,9 @@ in {
       { source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
         target = "NetworkManager/VPN/nm-openconnect-service.name";
       }
+      { source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
+        target = "NetworkManager/VPN/nm-pptp-service.name";
+      }
     ] ++ pkgs.lib.optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
            { source = overrideNameserversScript;
              target = "NetworkManager/dispatcher.d/02overridedns";
@@ -155,6 +158,7 @@ in {
         networkmanager_openvpn
         networkmanager_vpnc
         networkmanager_openconnect
+        networkmanager_pptp
         ];
 
     users.extraGroups = singleton {
@@ -199,6 +203,7 @@ in {
         networkmanager_openvpn
         networkmanager_vpnc
         networkmanager_openconnect
+        networkmanager_pptp
         ];
 
     services.udev.packages = cfg.packages;
diff --git a/nixos/modules/services/ttys/kmscon.nix b/nixos/modules/services/ttys/kmscon.nix
new file mode 100644
index 000000000000..6cb1ec648e55
--- /dev/null
+++ b/nixos/modules/services/ttys/kmscon.nix
@@ -0,0 +1,74 @@
+{ config, pkgs, ... }:
+let
+  inherit (pkgs.lib) mkOption types mkIf optionalString;
+
+  cfg = config.services.kmscon;
+
+  configDir = pkgs.writeTextFile { name = "kmscon-config"; destination = "/kmscon.conf"; text = cfg.extraConfig; };
+in {
+  options = {
+    services.kmscon = {
+      enable = mkOption {
+        description = ''
+          Use kmscon as the virtual console instead of gettys.
+          kmscon is a kms/dri-based userspace virtual terminal implementation.
+          It supports a richer feature set than the standard linux console VT,
+          including full unicode support, and when the video card supports drm
+          should be much faster.
+        '';
+        type = types.bool;
+        default = false;
+      };
+
+      hwRender = mkOption {
+        description = "Whether to use 3D hardware acceleration to render the console.";
+        type = types.bool;
+        default = false;
+      };
+
+      extraConfig = mkOption {
+        description = "Extra contents of the kmscon.conf file.";
+        type = types.lines;
+        default = "";
+        example = "font-size=14";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    # Largely copied from unit provided with kmscon source
+    systemd.units."kmsconvt@.service".text = ''
+      [Unit]
+      Description=KMS System Console on %I
+      Documentation=man:kmscon(1)
+      After=systemd-user-sessions.service
+      After=plymouth-quit-wait.service
+      After=systemd-logind.service
+      Requires=systemd-logind.service
+      Before=getty.target
+      Conflicts=getty@%i.service
+      OnFailure=getty@%i.service
+      IgnoreOnIsolate=yes
+      ConditionPathExists=/dev/tty0
+
+      [Service]
+      ExecStart=${pkgs.kmscon}/bin/kmscon "--vt=%I" --seats=seat0 --no-switchvt --configdir ${configDir} --login -- ${pkgs.shadow}/bin/login -p
+      UtmpIdentifier=%I
+      TTYPath=/dev/%I
+      TTYReset=yes
+      TTYVHangup=yes
+      TTYVTDisallocate=yes
+
+      X-RestartIfChanged=false
+    '';
+
+    systemd.units."autovt@.service".linkTarget = "${config.systemd.units."kmsconvt@.service".unit}/kmsconvt@.service";
+
+    services.kmscon.extraConfig = mkIf cfg.hwRender ''
+      drm
+      hwaccel
+    '';
+
+    services.mesa.enable = mkIf cfg.hwRender true;
+  };
+}
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index f06544fecc75..5e5fab3ed2bb 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -60,6 +60,7 @@ in
         pkgs.xfce.xfce4session
         pkgs.xfce.xfce4settings
         pkgs.xfce.xfce4mixer
+        pkgs.xfce.xfce4screenshooter
         pkgs.xfce.xfconf
         pkgs.xfce.xfdesktop
         pkgs.xfce.xfwm4
diff --git a/nixos/modules/services/x11/mesa.nix b/nixos/modules/services/x11/mesa.nix
new file mode 100644
index 000000000000..f892a1517582
--- /dev/null
+++ b/nixos/modules/services/x11/mesa.nix
@@ -0,0 +1,117 @@
+{ config, pkgs, pkgs_i686, ... }:
+let
+  inherit (pkgs.lib) mkOption types mkIf optional optionals elem optionalString optionalAttrs;
+
+  cfg = config.services.mesa;
+
+  kernelPackages = config.boot.kernelPackages;
+in {
+  options = {
+    services.mesa.enable = mkOption {
+      description = "Whether this configuration requires mesa.";
+      type = types.bool;
+      default = false;
+      internal = true;
+    };
+
+    services.mesa.driSupport = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether to enable accelerated OpenGL rendering through the
+        Direct Rendering Interface (DRI).
+      '';
+    };
+
+    services.mesa.driSupport32Bit = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        On 64-bit systems, whether to support Direct Rendering for
+        32-bit applications (such as Wine).  This is currently only
+        supported for the <literal>nvidia</literal> driver and for
+        <literal>mesa</literal>.
+      '';
+    };
+
+    services.mesa.s3tcSupport = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Make S3TC(S3 Texture Compression) via libtxc_dxtn available
+        to OpenGL drivers. It is essential for many games to work
+        with FOSS GPU drivers.
+
+        Using this library may require a patent license depending on your location.
+      '';
+    };
+
+
+    services.mesa.videoDrivers = mkOption {
+      type = types.listOf types.str;
+      # !!! We'd like "nv" here, but it segfaults the X server.
+      default = [ "ati" "cirrus" "intel" "vesa" "vmware" ];
+      example = [ "vesa" ];
+      description = ''
+        The names of the video drivers that the mesa should
+        support.  Mesa will try all of the drivers listed
+        here until it finds one that supports your video card.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    system.activationScripts.setup-opengl.deps = [];
+    system.activationScripts.setup-opengl.text = ''
+      rm -f /run/opengl-driver{,-32}
+      ${optionalString (!cfg.driSupport32Bit) "ln -sf opengl-driver /run/opengl-driver-32"}
+
+      ${# !!! The OpenGL driver depends on what's detected at runtime.
+        if elem "nvidia" cfg.videoDrivers then
+          ''
+            ln -sf ${kernelPackages.nvidia_x11} /run/opengl-driver
+            ${optionalString cfg.driSupport32Bit
+              "ln -sf ${pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernel = null; } } /run/opengl-driver-32"}
+          ''
+        else if elem "nvidiaLegacy173" cfg.videoDrivers then
+          "ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver"
+        else if elem "nvidiaLegacy304" cfg.videoDrivers then
+          ''
+            ln -sf ${kernelPackages.nvidia_x11_legacy304} /run/opengl-driver
+            ${optionalString cfg.driSupport32Bit
+              "ln -sf ${pkgs_i686.linuxPackages.nvidia_x11_legacy304.override { libsOnly = true; kernel = null; } } /run/opengl-driver-32"}
+          ''
+        else if elem "ati_unfree" cfg.videoDrivers then
+          "ln -sf ${kernelPackages.ati_drivers_x11} /run/opengl-driver"
+        else
+          ''
+            ${optionalString cfg.driSupport "ln -sf ${pkgs.mesa_drivers} /run/opengl-driver"}
+            ${optionalString cfg.driSupport32Bit
+              "ln -sf ${pkgs_i686.mesa_drivers} /run/opengl-driver-32"}
+          ''
+      }
+    '';
+
+    environment.variables.LD_LIBRARY_PATH =
+      [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]
+      ++ optional cfg.s3tcSupport "${pkgs.libtxc_dxtn}/lib"
+      ++ optional (cfg.s3tcSupport && cfg.driSupport32Bit) "${pkgs_i686.libtxc_dxtn}/lib";
+
+    boot.extraModulePackages =
+      optional (elem "nvidia" cfg.videoDrivers) kernelPackages.nvidia_x11 ++
+      optional (elem "nvidiaLegacy173" cfg.videoDrivers) kernelPackages.nvidia_x11_legacy173 ++
+      optional (elem "nvidiaLegacy304" cfg.videoDrivers) kernelPackages.nvidia_x11_legacy304 ++
+      optional (elem "virtualbox" cfg.videoDrivers) kernelPackages.virtualboxGuestAdditions ++
+      optional (elem "ati_unfree" cfg.videoDrivers) kernelPackages.ati_drivers_x11;
+
+    boot.blacklistedKernelModules =
+      optionals (elem "nvidia" cfg.videoDrivers) [ "nouveau" "nvidiafb" ];
+
+    environment.etc =  (optionalAttrs (elem "ati_unfree" cfg.videoDrivers) {
+        "ati".source = "${kernelPackages.ati_drivers_x11}/etc/ati";
+      })
+      // (optionalAttrs (elem "nvidia" cfg.videoDrivers) {
+        "OpenCL/vendors/nvidia.icd".source = "${kernelPackages.nvidia_x11}/lib/vendors/nvidia.icd";
+      });
+  };
+}
diff --git a/nixos/modules/services/x11/xserver.nix b/nixos/modules/services/x11/xserver.nix
index 0253c70f2dd4..5600ce7fac13 100644
--- a/nixos/modules/services/x11/xserver.nix
+++ b/nixos/modules/services/x11/xserver.nix
@@ -16,15 +16,13 @@ let
     ati_unfree   = { modules = [ kernelPackages.ati_drivers_x11 ]; driverName = "fglrx"; };
     nouveau       = { modules = [ pkgs.xf86_video_nouveau ]; };
     nvidia       = { modules = [ kernelPackages.nvidia_x11 ]; };
-    nvidiaLegacy96 = { modules = [ kernelPackages.nvidia_x11_legacy96 ]; driverName = "nvidia"; };
     nvidiaLegacy173 = { modules = [ kernelPackages.nvidia_x11_legacy173 ]; driverName = "nvidia"; };
     nvidiaLegacy304 = { modules = [ kernelPackages.nvidia_x11_legacy304 ]; driverName = "nvidia"; };
     unichrome    = { modules = [ pkgs.xorgVideoUnichrome ]; };
     virtualbox   = { modules = [ kernelPackages.virtualboxGuestAdditions ]; driverName = "vboxvideo"; };
   };
 
-  driverNames =
-    optional (cfg.videoDriver != null) cfg.videoDriver ++ cfg.videoDrivers;
+  driverNames = config.services.mesa.videoDrivers;
 
   drivers = flip map driverNames
     (name: { inherit name; driverName = name; } //
@@ -183,19 +181,7 @@ in
         description = ''
           The name of the video driver for your graphics card.  This
           option is obsolete; please set the
-          <option>videoDrivers</option> instead.
-        '';
-      };
-
-      videoDrivers = mkOption {
-        type = types.listOf types.str;
-        # !!! We'd like "nv" here, but it segfaults the X server.
-        default = [ "ati" "cirrus" "intel" "vesa" "vmware" ];
-        example = [ "vesa" ];
-        description = ''
-          The names of the video drivers that the X server should
-          support.  The X server will try all of the drivers listed
-          here until it finds one that supports your video card.
+          <option>services.mesa.videoDrivers</option> instead.
         '';
       };
 
@@ -208,38 +194,6 @@ in
         '';
       };
 
-      driSupport = mkOption {
-        type = types.bool;
-        default = true;
-        description = ''
-          Whether to enable accelerated OpenGL rendering through the
-          Direct Rendering Interface (DRI).
-        '';
-      };
-
-      driSupport32Bit = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          On 64-bit systems, whether to support Direct Rendering for
-          32-bit applications (such as Wine).  This is currently only
-          supported for the <literal>nvidia</literal> driver and for
-          <literal>mesa</literal>.
-        '';
-      };
-
-      s3tcSupport = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Make S3TC(S3 Texture Compression) via libtxc_dxtn available
-          to OpenGL drivers. It is essential for many games to work
-          with FOSS GPU drivers.
-
-          Using this library may require a patent license depending on your location.
-        '';
-      };
-
       startOpenSSHAgent = mkOption {
         type = types.bool;
         default = true;
@@ -427,6 +381,8 @@ in
   ###### implementation
 
   config = mkIf cfg.enable {
+    services.mesa.enable = true;
+    services.mesa.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ];
 
     assertions =
       [ { assertion = !(cfg.startOpenSSHAgent && cfg.startGnuPGAgent);
@@ -441,22 +397,6 @@ in
         }
       ];
 
-    boot.extraModulePackages =
-      optional (elem "nvidia" driverNames) kernelPackages.nvidia_x11 ++
-      optional (elem "nvidiaLegacy96" driverNames) kernelPackages.nvidia_x11_legacy96 ++
-      optional (elem "nvidiaLegacy173" driverNames) kernelPackages.nvidia_x11_legacy173 ++
-      optional (elem "nvidiaLegacy304" driverNames) kernelPackages.nvidia_x11_legacy304 ++
-      optional (elem "virtualbox" driverNames) kernelPackages.virtualboxGuestAdditions ++
-      optional (elem "ati_unfree" driverNames) kernelPackages.ati_drivers_x11;
-
-    boot.blacklistedKernelModules =
-      optionals (elem "nvidia" driverNames) [ "nouveau" "nvidiafb" ];
-
-    environment.variables.LD_LIBRARY_PATH =
-      [ "/run/opengl-driver/lib" "/run/opengl-driver-32/lib" ]
-      ++ pkgs.lib.optional cfg.s3tcSupport "${pkgs.libtxc_dxtn}/lib"
-      ++ pkgs.lib.optional (cfg.s3tcSupport && cfg.driSupport32Bit) "${pkgs_i686.libtxc_dxtn}/lib";
-
     environment.etc =
       (optionals cfg.exportConfiguration
         [ { source = "${configFile}";
@@ -466,21 +406,7 @@ in
           { source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
             target = "X11/xkb";
           }
-        ])
-      ++ (optionals (elem "ati_unfree" driverNames) [
-
-          # according toiive on #ati you don't need the pcs, it is like registry... keeps old stuff to make your
-          # life harder ;) Still it seems to be required
-          { source = "${kernelPackages.ati_drivers_x11}/etc/ati";
-            target = "ati";
-          }
-      ])
-      ++ (optionals (elem "nvidia" driverNames) [
-
-          { source = "${kernelPackages.nvidia_x11}/lib/vendors/nvidia.icd";
-            target = "OpenCL/vendors/nvidia.icd";
-          }
-      ]);
+        ]);
 
     environment.systemPackages =
       [ xorg.xorgserver
@@ -497,7 +423,6 @@ in
         pkgs.xdg_utils
       ]
       ++ optional (elem "nvidia" driverNames) kernelPackages.nvidia_x11
-      ++ optional (elem "nvidiaLegacy96" driverNames) kernelPackages.nvidia_x11_legacy96
       ++ optional (elem "nvidiaLegacy173" driverNames) kernelPackages.nvidia_x11_legacy173
       ++ optional (elem "nvidiaLegacy304" driverNames) kernelPackages.nvidia_x11_legacy304
       ++ optional (elem "virtualbox" driverNames) xorg.xrefresh
@@ -521,8 +446,6 @@ in
             XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
           } // optionalAttrs (elem "nvidia" driverNames) {
             LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11}/lib";
-          } // optionalAttrs (elem "nvidiaLegacy96" driverNames) {
-            LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11_legacy96}/lib";
           } // optionalAttrs (elem "nvidiaLegacy173" driverNames) {
             LD_LIBRARY_PATH = "${xorg.libX11}/lib:${xorg.libXext}/lib:${kernelPackages.nvidia_x11_legacy173}/lib";
           } // optionalAttrs (elem "nvidiaLegacy304" driverNames) {
@@ -534,36 +457,6 @@ in
 
         preStart =
           ''
-            rm -f /run/opengl-driver{,-32}
-            ${optionalString (!cfg.driSupport32Bit) "ln -sf opengl-driver /run/opengl-driver-32"}
-
-            ${# !!! The OpenGL driver depends on what's detected at runtime.
-              if elem "nvidia" driverNames then
-                ''
-                  ln -sf ${kernelPackages.nvidia_x11} /run/opengl-driver
-                  ${optionalString cfg.driSupport32Bit
-                    "ln -sf ${pkgs_i686.linuxPackages.nvidia_x11.override { libsOnly = true; kernelDev = null; } } /run/opengl-driver-32"}
-                ''
-              else if elem "nvidiaLegacy96" driverNames then
-                "ln -sf ${kernelPackages.nvidia_x11_legacy96} /run/opengl-driver"
-              else if elem "nvidiaLegacy173" driverNames then
-                "ln -sf ${kernelPackages.nvidia_x11_legacy173} /run/opengl-driver"
-              else if elem "nvidiaLegacy304" driverNames then
-                ''
-                  ln -sf ${kernelPackages.nvidia_x11_legacy304} /run/opengl-driver
-                  ${optionalString cfg.driSupport32Bit
-                    "ln -sf ${pkgs_i686.linuxPackages.nvidia_x11_legacy304.override { libsOnly = true; kernelDev = null; } } /run/opengl-driver-32"}
-                ''
-              else if elem "ati_unfree" driverNames then
-                "ln -sf ${kernelPackages.ati_drivers_x11} /run/opengl-driver"
-              else
-                ''
-                  ${optionalString cfg.driSupport "ln -sf ${pkgs.mesa_drivers} /run/opengl-driver"}
-                  ${optionalString cfg.driSupport32Bit
-                    "ln -sf ${pkgs_i686.mesa_drivers} /run/opengl-driver-32"}
-                ''
-            }
-
             ${cfg.displayManager.job.preStart}
 
             rm -f /tmp/.X0-lock
diff --git a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
index 9193cd3bc533..7edc30776379 100644
--- a/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
+++ b/nixos/modules/system/boot/loader/gummiboot/gummiboot.nix
@@ -14,7 +14,7 @@ let
 
     inherit (pkgs) python gummiboot;
 
-    inherit (config.environment) nix;
+    nix = config.nix.package;
 
     inherit (cfg) timeout;
 
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index 75c2c788f384..b12031d24adc 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -11,13 +11,16 @@ let
   systemd = cfg.package;
 
   makeUnit = name: unit:
-    pkgs.runCommand "unit" { inherit (unit) text; preferLocalBuild = true; }
-      (if unit.enable then  ''
+    pkgs.runCommand "unit" ({ preferLocalBuild = true; } // optionalAttrs (unit.linkTarget == null) { inherit (unit) text; })
+      (if !unit.enable then  ''
         mkdir -p $out
-        echo -n "$text" > $out/${name}
+        ln -s /dev/null $out/${name}
+      '' else if unit.linkTarget != null then ''
+        mkdir -p $out
+        ln -s ${unit.linkTarget} $out/${name}
       '' else ''
         mkdir -p $out
-        ln -s /dev/null $out/${name}
+        echo -n "$text" > $out/${name}
       '');
 
   upstreamUnits =
@@ -338,7 +341,7 @@ let
       done
 
       for i in ${toString (mapAttrsToList (n: v: v.unit) cfg.units)}; do
-        ln -s $i/* $out/
+        ln -fs $i/* $out/
       done
 
       for i in ${toString cfg.packages}; do
@@ -362,7 +365,7 @@ let
       ln -s rescue.target $out/kbrequest.target
 
       mkdir -p $out/getty.target.wants/
-      ln -s ../getty@tty1.service $out/getty.target.wants/
+      ln -s ../autovt@tty1.service $out/getty.target.wants/
 
       ln -s ../local-fs.target ../remote-fs.target ../network.target ../nss-lookup.target \
             ../nss-user-lookup.target ../swap.target $out/multi-user.target.wants/
@@ -416,6 +419,11 @@ in
               internal = true;
               description = "The generated unit.";
             };
+            linkTarget = mkOption {
+              default = null;
+              description = "The file to symlink this target to.";
+              type = types.nullOr types.path;
+            };
           };
           config = {
             unit = makeUnit name config;
diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl
index 7cb6d2a6a45e..4b79dbaab89e 100644
--- a/nixos/modules/system/etc/setup-etc.pl
+++ b/nixos/modules/system/etc/setup-etc.pl
@@ -57,9 +57,13 @@ sub link {
         open MODE, "<$_.mode";
         my $mode = <MODE>; chomp $mode;
         close MODE;
-        copy "$static/$fn", "$target.tmp" or warn;
-        chmod oct($mode), "$target.tmp" or warn;
-        rename "$target.tmp", $target or warn;
+        if ($mode eq "direct-symlink") {
+            atomicSymlink readlink("$static/$fn"), $target or warn;
+        } else {
+            copy "$static/$fn", "$target.tmp" or warn;
+            chmod oct($mode), "$target.tmp" or warn;
+            rename "$target.tmp", $target or warn;
+        }
     } elsif (-l "$_") {
         atomicSymlink "$static/$fn", $target or warn;
     }