diff --git a/doc/config-examples/svn-server.nix b/doc/config-examples/svn-server.nix index 7f2dafe16adb..a3c3b46cf244 100644 --- a/doc/config-examples/svn-server.nix +++ b/doc/config-examples/svn-server.nix @@ -17,6 +17,7 @@ httpd = { enable = true; + experimental = true; adminAddr = "admin@example.org"; subservices = { diff --git a/etc/default.nix b/etc/default.nix index fc07a39f9be7..8579b334e672 100644 --- a/etc/default.nix +++ b/etc/default.nix @@ -129,32 +129,6 @@ let target = "inputrc"; } - { # Nix configuration. - source = - let - # Tricky: if we're using a chroot for builds, then we need - # /bin/sh in the chroot (our own compromise to purity). - # However, since /bin/sh is a symlink to some path in the - # Nix store, which furthermore has runtime dependencies on - # other paths in the store, we need the closure of /bin/sh - # in `build-chroot-dirs' - otherwise any builder that uses - # /bin/sh won't work. - refs = pkgs.writeReferencesToFile binsh; - in - pkgs.runCommand "nix.conf" {} '' - binshDeps=$(for i in $(cat ${refs}); do if test -d $i; then echo $i; fi; done) - cat > $out <nixos-checkout will update all working + copies of the given repositories, + nixos-rebuild will use the first item + which has the attribute default = true + falling back to the first item. The type defines the + repository tool added to the path. It also defines a "valid" + repository. If the target directory already exists and it's + not valid it will be moved to the backup location + dir-date. + For svn the default target and repositories are + /etc/nixos/nixos and + https://svn.nixos.org/repos/nix/nixos/trunk. + For git repositories update is called after initialization + when the repo is initialized. The initialize code is run + from working directory dirname + target and should create the + directory + dir. (git + clone url nixos/nixpkgs/services should do) For + the executables used see . + ''; + }; + + nixpkgs = mkOption { + default = [ { type = "svn"; } ]; + description = "same as "; + }; + + services = mkOption { + default = [ { type = "svn"; } ]; + description = "same as "; + }; + }; + + repoTypes = mkOption { + default = { + svn = { valid = "[ -d .svn ]"; env = [ pkgs.coreutils pkgs.subversion ]; }; + git = { valid = "[ -d .git ]"; env = [ pkgs.coreutils pkgs.git pkgs.gnused /* FIXME: use full path to sed in nix-pull */ ]; }; + }; + description = '' + Defines, for each supported version control system + (e.g. git), the dependencies for the + mechanism, as well as a test used to determine whether a + directory is a checkout created by that version control + system. + ''; + }; + + manifests = mkOption { + default = [http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST]; + example = + [ http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST + http://nixos.org/releases/nixpkgs/channels/nixpkgs-stable/MANIFEST + ]; + description = " + URLs of manifests to be downloaded when you run + nixos-rebuild to speed up builds. + "; + }; + }; + }; + + +in + +###### implementation + +mkIf config.services.pulseaudio.enable { + require = [ + options + ]; + +} diff --git a/system/nixos-security.nix b/system/nixos-security.nix new file mode 100644 index 000000000000..10d523ee339a --- /dev/null +++ b/system/nixos-security.nix @@ -0,0 +1,49 @@ +{pkgs, config, ...}: +let + inherit (pkgs.lib) mergeOneOption mkOption mkIf; +in +{ + require = [ + { + security = { + setuidPrograms = mkOption { + default = [ + "passwd" "su" "crontab" "ping" "ping6" + "fusermount" "wodim" "cdrdao" "growisofs" + ]; + description = " + Only the programs from system path listed her will be made setuid root + (through a wrapper program). It's better to set + . + "; + }; + + extraSetuidPrograms = mkOption { + default = []; + example = ["fusermount"]; + description = " + This option lists additional programs that must be made setuid + root. + "; + }; + + setuidOwners = mkOption { + default = []; + example = [{ + program = "sendmail"; + owner = "nodody"; + group = "postdrop"; + setuid = false; + setgid = true; + }]; + description = '' + List of non-trivial setuid programs from system path, like Postfix sendmail. Default + should probably be nobody:nogroup:false:false - if you are bothering + doing anything with a setuid program, "root.root u+s g-s" is not what + you are aiming at.. + ''; + }; + }; + } + ]; +} diff --git a/system/options.nix b/system/options.nix index 34ae64a3c51b..53a3d11d7f66 100644 --- a/system/options.nix +++ b/system/options.nix @@ -245,29 +245,6 @@ in "; }; - interfaceMonitor = { - - enable = mkOption { - default = false; - description = " - If true, monitor Ethernet interfaces for - cables being plugged in or unplugged. When this occurs, the - dhclient service is restarted to - automatically obtain a new IP address. This is useful for - roaming users (laptops). - "; - }; - - beep = mkOption { - default = false; - description = " - If true, beep when an Ethernet cable is - plugged in or unplugged. - "; - }; - - }; - defaultMailServer = { directDelivery = mkOption { @@ -380,1826 +357,6 @@ in "; }; - servicesProposal = { - # see upstart-jobs/default.nix - # the option declarations can be found in the upstart-jobs/newProposal/*.nix files - # one way to include the declarations here is adding kind of glob "*.nix" - # file function to builtins to get all jobs - # then the checking in upstart-jobs/default.nix can be removed again (together with passing arg optionDeclarations) - }; - - services = { - - - syslogd = { - - tty = mkOption { - default = 10; - description = " - The tty device on which syslogd will print important log - messages. - "; - }; - - }; - - - ttyBackgrounds = { - - enable = mkOption { - default = true; - description = " - Whether to enable graphical backgrounds for the virtual consoles. - "; - }; - - defaultTheme = mkOption { - default = pkgs.fetchurl { - #url = http://www.bootsplash.de/files/themes/Theme-BabyTux.tar.bz2; - url = http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/distfiles/Theme-BabyTux.tar.bz2; - md5 = "a6d89d1c1cff3b6a08e2f526f2eab4e0"; - }; - description = " - The default theme for the virtual consoles. Themes can be found - at . - "; - }; - - defaultSpecificThemes = mkOption { - default = [ - /* - { tty = 6; - theme = pkgs.fetchurl { # Yeah! - url = http://www.bootsplash.de/files/themes/Theme-Pativo.tar.bz2; - md5 = "9e13beaaadf88d43a5293e7ab757d569"; - }; - } - */ - { tty = 10; - theme = pkgs.fetchurl { - #url = http://www.bootsplash.de/files/themes/Theme-GNU.tar.bz2; - url = http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/distfiles/Theme-GNU.tar.bz2; - md5 = "61969309d23c631e57b0a311102ef034"; - }; - } - ]; - description = " - This option sets specific themes for virtual consoles. If you - just want to set themes for additional consoles, use - . - "; - }; - - specificThemes = mkOption { - default = [ - ]; - description = " - This option allows you to set specific themes for virtual - consoles. - "; - }; - - }; - - - mingetty = { - - ttys = mkOption { - default = [1 2 3 4 5 6]; - description = " - The list of tty (virtual console) devices on which to start a - login prompt. - "; - }; - - waitOnMounts = mkOption { - default = false; - description = " - Whether the login prompts on the virtual consoles will be - started before or after all file systems have been mounted. By - default we don't wait, but if for example your /home is on a - separate partition, you may want to turn this on. - "; - }; - - greetingLine = mkOption { - default = ''<<< Welcome to NixOS (\m) - Kernel \r (\l) >>>''; - description = " - Welcome line printed by mingetty. - "; - }; - - helpLine = mkOption { - default = ""; - description = " - Help line printed by mingetty below the welcome line. - Used by the installation CD to give some hints on - how to proceed. - "; - }; - - }; - - - dhcpd = { - - enable = mkOption { - default = false; - description = " - Whether to enable the DHCP server. - "; - }; - - extraConfig = mkOption { - default = ""; - example = " - option subnet-mask 255.255.255.0; - option broadcast-address 192.168.1.255; - option routers 192.168.1.5; - option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1; - option domain-name \"example.org\"; - subnet 192.168.1.0 netmask 255.255.255.0 { - range 192.168.1.100 192.168.1.200; - } - "; - description = " - Extra text to be appended to the DHCP server configuration - file. Currently, you almost certainly need to specify - something here, such as the options specifying the subnet - mask, DNS servers, etc. - "; - }; - - configFile = mkOption { - default = null; - description = " - The path of the DHCP server configuration file. If no file - is specified, a file is generated using the other options. - "; - }; - - interfaces = mkOption { - default = ["eth0"]; - description = " - The interfaces on which the DHCP server should listen. - "; - }; - - machines = mkOption { - default = []; - example = [ - { hostName = "foo"; - ethernetAddress = "00:16:76:9a:32:1d"; - ipAddress = "192.168.1.10"; - } - { hostName = "bar"; - ethernetAddress = "00:19:d1:1d:c4:9a"; - ipAddress = "192.168.1.11"; - } - ]; - description = " - A list mapping ethernet addresses to IP addresses for the - DHCP server. - "; - }; - - }; - - - sshd = { - - enable = mkOption { - default = false; - description = " - Whether to enable the Secure Shell daemon, which allows secure - remote logins. - "; - }; - - forwardX11 = mkOption { - default = true; - description = " - Whether to enable sshd to forward X11 connections. - "; - }; - - allowSFTP = mkOption { - default = true; - description = " - Whether to enable the SFTP subsystem in the SSH daemon. This - enables the use of commands such as sftp and - sshfs. - "; - }; - - permitRootLogin = mkOption { - default = "yes"; - description = " - Whether the root user can login using ssh. Valid options - are yes, without-password, - forced-commands-only or - no - "; - }; - - gatewayPorts = mkOption { - default = "no"; - description = " - Specifies whether remote hosts are allowed to connect to ports forwarded for the client. See man sshd_conf. - "; - }; - }; - - lshd = { - - enable = mkOption { - default = false; - description = '' - Whether to enable the GNU lshd SSH2 daemon, which allows - secure remote login. - ''; - }; - - portNumber = mkOption { - default = 22; - description = '' - The port on which to listen for connections. - ''; - }; - - interfaces = mkOption { - default = []; - description = '' - List of network interfaces where listening for connections. - When providing the empty list, `[]', lshd listens on all - network interfaces. - ''; - example = [ "localhost" "1.2.3.4:443" ]; - }; - - hostKey = mkOption { - default = "/etc/lsh/host-key"; - description = '' - Path to the server's private key. Note that this key must - have been created, e.g., using "lsh-keygen --server | - lsh-writekey --server", so that you can run lshd. - ''; - }; - - syslog = mkOption { - default = true; - description = ''Whether to enable syslog output.''; - }; - - passwordAuthentication = mkOption { - default = true; - description = ''Whether to enable password authentication.''; - }; - - publicKeyAuthentication = mkOption { - default = true; - description = ''Whether to enable public key authentication.''; - }; - - rootLogin = mkOption { - default = false; - description = ''Whether to enable remote root login.''; - }; - - loginShell = mkOption { - default = null; - description = '' - If non-null, override the default login shell with the - specified value. - ''; - example = "/nix/store/xyz-bash-10.0/bin/bash10"; - }; - - srpKeyExchange = mkOption { - default = false; - description = '' - Whether to enable SRP key exchange and user authentication. - ''; - }; - - tcpForwarding = mkOption { - default = true; - description = ''Whether to enable TCP/IP forwarding.''; - }; - - x11Forwarding = mkOption { - default = true; - description = ''Whether to enable X11 forwarding.''; - }; - - subsystems = mkOption { - default = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; - description = '' - List of subsystem-path pairs, where the head of the pair - denotes the subsystem name, and the tail denotes the path to - an executable implementing it. - ''; - }; - }; - - ntp = { - - enable = mkOption { - default = true; - description = " - Whether to synchronise your machine's time using the NTP - protocol. - "; - }; - - servers = mkOption { - default = [ - "0.pool.ntp.org" - "1.pool.ntp.org" - "2.pool.ntp.org" - ]; - description = " - The set of NTP servers from which to synchronise. - "; - }; - - }; - - portmap = { - - enable = mkOption { - default = false; - description = '' - Whether to enable `portmap', an ONC RPC directory service - notably used by NFS and NIS, and which can be queried - using the rpcinfo(1) command. - ''; - }; - }; - - bitlbee = { - - enable = mkOption { - default = false; - description = '' - Whether to run the BitlBee IRC to other chat network gateway. - Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat - networks via an IRC client. - ''; - }; - - interface = mkOption { - default = "127.0.0.1"; - description = '' - The interface the BitlBee deamon will be listening to. If `127.0.0.1', - only clients on the local host can connect to it; if `0.0.0.0', clients - can access it from any network interface. - ''; - }; - - portNumber = mkOption { - default = 6667; - description = '' - Number of the port BitlBee will be listening to. - ''; - }; - - }; - - gnunet = { - - enable = mkOption { - default = false; - description = '' - Whether to run the GNUnet daemon. GNUnet is GNU's anonymous - peer-to-peer communication and file sharing framework. - ''; - }; - - home = mkOption { - default = "/var/lib/gnunet"; - description = '' - Directory where the GNUnet daemon will store its data. - ''; - }; - - debug = mkOption { - default = false; - description = '' - When true, run in debug mode; gnunetd will not daemonize and - error messages will be written to stderr instead of a - logfile. - ''; - }; - - logLevel = mkOption { - default = "ERROR"; - example = "INFO"; - description = '' - Log level of the deamon (see `gnunetd(1)' for details). - ''; - }; - - hostLists = mkOption { - default = [ - "http://gnunet.org/hostlist.php" - "http://gnunet.mine.nu:8081/hostlist" - "http://vserver1236.vserver-on.de/hostlist-074" - ]; - description = '' - URLs of host lists. - ''; - }; - - - applications = mkOption { - default = [ "advertising" "getoption" "fs" "stats" "traffic" ]; - example = [ "chat" "fs" ]; - description = '' - List of GNUnet applications supported by the daemon. Note that - `fs', which means "file sharing", is probably the one you want. - ''; - }; - - transports = mkOption { - default = [ "udp" "tcp" "http" "nat" ]; - example = [ "smtp" "http" ]; - description = '' - List of transport methods used by the server. - ''; - }; - - fileSharing = { - quota = mkOption { - default = 1024; - description = '' - Maximum file system usage (in MiB) for file sharing. - ''; - }; - - activeMigration = mkOption { - default = false; - description = '' - Whether to allow active migration of content originating - from other nodes. - ''; - }; - }; - - load = { - maxNetDownBandwidth = mkOption { - default = 50000; - description = '' - Maximum bandwidth usage (in bits per second) for GNUnet - when downloading data. - ''; - }; - - maxNetUpBandwidth = mkOption { - default = 50000; - description = '' - Maximum bandwidth usage (in bits per second) for GNUnet - when downloading data. - ''; - }; - - hardNetUpBandwidth = mkOption { - default = 0; - description = '' - Hard bandwidth limit (in bits per second) when uploading - data. - ''; - }; - - maxCPULoad = mkOption { - default = 100; - description = '' - Maximum CPU load (percentage) authorized for the GNUnet - daemon. - ''; - }; - - interfaces = mkOption { - default = [ "eth0" ]; - example = [ "wlan0" "eth1" ]; - description = '' - List of network interfaces to use. - ''; - }; - }; - - extraOptions = mkOption { - default = ""; - example = '' - [NETWORK] - INTERFACE = eth3 - ''; - description = '' - Additional options that will be copied verbatim in `gnunetd.conf'. - See `gnunetd.conf(5)' for details. - ''; - }; - }; - - - ejabberd = { - enable = mkOption { - default = false; - description = "Whether to enable ejabberd server"; - }; - - spoolDir = mkOption { - default = "/var/lib/ejabberd"; - description = "Location of the spooldir of ejabberd"; - }; - - logsDir = mkOption { - default = "/var/log/ejabberd"; - description = "Location of the logfile directory of ejabberd"; - }; - - confDir = mkOption { - default = "/var/ejabberd"; - description = "Location of the config directory of ejabberd"; - }; - - virtualHosts = mkOption { - default = "\"localhost\""; - description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; - }; - }; - - jboss = { - enable = mkOption { - default = false; - description = "Whether to enable jboss"; - }; - - tempDir = mkOption { - default = "/tmp"; - description = "Location where JBoss stores its temp files"; - }; - - logDir = mkOption { - default = "/var/log/jboss"; - description = "Location of the logfile directory of JBoss"; - }; - - serverDir = mkOption { - description = "Location of the server instance files"; - default = "/var/jboss/server"; - }; - - deployDir = mkOption { - description = "Location of the deployment files"; - default = "/nix/var/nix/profiles/default/server/default/deploy/"; - }; - - libUrl = mkOption { - default = "file:///nix/var/nix/profiles/default/server/default/lib"; - description = "Location where the shared library JARs are stored"; - }; - - user = mkOption { - default = "nobody"; - description = "User account under which jboss runs."; - }; - - useJK = mkOption { - default = false; - description = "Whether to use to connector to the Apache HTTP server"; - }; - }; - - tomcat = { - enable = mkOption { - default = false; - description = "Whether to enable Apache Tomcat"; - }; - - baseDir = mkOption { - default = "/var/tomcat"; - description = "Location where Tomcat stores configuration files, webapplications and logfiles"; - }; - - user = mkOption { - default = "tomcat"; - description = "User account under which Apache Tomcat runs."; - }; - - deployFrom = mkOption { - default = ""; - description = "Location where webapplications are stored. Leave empty to use the baseDir."; - }; - - javaOpts = mkOption { - default = ""; - description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; - }; - - catalinaOpts = mkOption { - default = ""; - description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; - }; - - sharedLibFrom = mkOption { - default = ""; - description = "Location where shared libraries are stored. Leave empty to use the baseDir."; - }; - - commonLibFrom = mkOption { - default = ""; - description = "Location where common libraries are stored. Leave empty to use the baseDir."; - }; - - contextXML = mkOption { - default = ""; - description = "Location of the context.xml to use. Leave empty to use the default."; - }; - }; - - httpd = { - - enable = mkOption { - default = false; - description = " - Whether to enable the Apache httpd server. - "; - }; - - experimental = mkOption { - default = false; - description = " - Whether to use the new-style Apache configuration. - "; - }; - - extraConfig = mkOption { - default = ""; - description = " - These configuration lines will be passed verbatim to the apache config - "; - }; - - extraModules = mkOption { - default = []; - example = [ "proxy_connect" { name = "php5_module"; path = "${pkgs.php}/modules/libphp5.so"; } ]; - description = '' - Specifies additional Apache modules. These can be specified - as a string in the case of modules distributed with Apache, - or as an attribute set specifying the - name and path of the - module. - ''; - }; - - logPerVirtualHost = mkOption { - default = false; - description = " - If enabled, each virtual host gets its own - access_log and - error_log, namely suffixed by the - of the virtual host. - "; - }; - - user = mkOption { - default = "wwwrun"; - description = " - User account under which httpd runs. The account is created - automatically if it doesn't exist. - "; - }; - - group = mkOption { - default = "wwwrun"; - description = " - Group under which httpd runs. The account is created - automatically if it doesn't exist. - "; - }; - - logDir = mkOption { - default = "/var/log/httpd"; - description = " - Directory for Apache's log files. It is created automatically. - "; - }; - - stateDir = mkOption { - default = "/var/run/httpd"; - description = " - Directory for Apache's transient runtime state (such as PID - files). It is created automatically. Note that the default, - /var/run/httpd, is deleted at boot time. - "; - }; - - mod_php = mkOption { - default = false; - description = "Whether to enable the PHP module."; - }; - - mod_jk = { - enable = mkOption { - default = false; - description = "Whether to enable the Apache Tomcat connector."; - }; - - applicationMappings = mkOption { - default = []; - description = "List of Java webapplications that should be mapped to the servlet container (Tomcat/JBoss)"; - }; - }; - - virtualHosts = mkOption { - default = []; - example = [ - { hostName = "foo"; - documentRoot = "/data/webroot-foo"; - } - { hostName = "bar"; - documentRoot = "/data/webroot-bar"; - } - ]; - description = '' - Specification of the virtual hosts served by Apache. Each - element should be an attribute set specifying the - configuration of the virtual host. The available options - are the non-global options permissible for the main host. - ''; - }; - - subservices = { - - # !!! remove this - subversion = { - - enable = mkOption { - default = false; - description = " - Whether to enable the Subversion subservice in the webserver. - "; - }; - - notificationSender = mkOption { - default = "svn-server@example.org"; - example = "svn-server@example.org"; - description = " - The email address used in the Sender field of commit - notification messages sent by the Subversion subservice. - "; - }; - - userCreationDomain = mkOption { - default = "example.org"; - example = "example.org"; - description = " - The domain from which user creation is allowed. A client can - only create a new user account if its IP address resolves to - this domain. - "; - }; - - autoVersioning = mkOption { - default = false; - description = " - Whether you want the Subversion subservice to support - auto-versioning, which enables Subversion repositories to be - mounted as read/writable file systems on operating systems that - support WebDAV. - "; - }; - - dataDir = mkOption { - default = "/no/such/path/exists"; - description = " - Place to put SVN repository. - "; - }; - - organization = { - - name = mkOption { - default = null; - description = " - Name of the organization hosting the Subversion service. - "; - }; - - url = mkOption { - default = null; - description = " - URL of the website of the organization hosting the Subversion service. - "; - }; - - logo = mkOption { - default = null; - description = " - Logo the organization hosting the Subversion service. - "; - }; - - }; - - }; - - }; - - } // # Include the options shared between the main server and virtual hosts. - (import ../upstart-jobs/apache-httpd/per-server-options.nix { - inherit mkOption; - forMainServer = true; - }); - - vsftpd = { - enable = mkOption { - default = false; - description = " - Whether to enable the vsftpd FTP server. - "; - }; - - anonymousUser = mkOption { - default = false; - description = " - Whether to enable the anonymous FTP user. - "; - }; - - writeEnable = mkOption { - default = false; - description = " - Whether any write activity is permitted to users. - "; - }; - - anonymousUploadEnable = mkOption { - default = false; - description = " - Whether any uploads are permitted to anonymous users. - "; - }; - - anonymousMkdirEnable = mkOption { - default = false; - description = " - Whether mkdir is permitted to anonymous users. - "; - }; - }; - - printing = { - - enable = mkOption { - default = false; - description = " - Whether to enable printing support through the CUPS daemon. - "; - }; - - }; - - - udev = { - - addFirmware = mkOption { - default = []; - example = ["/mnt/big-storage/firmware/"]; - description = " - To specify firmware that is not too spread to ensure - a package, or have an interactive process of extraction - and cannot be redistributed. - "; - merge = pkgs.lib.mergeListOption; - }; - - addUdevPkgs = mkOption { - default = []; - description = " - List of packages containing udev rules. - "; - merge = pkgs.lib.mergeListOption; - }; - - sndMode = mkOption { - default = "0600"; - example = "0666"; - description = " - Permissions for /dev/snd/*, in case you have multiple - logged in users or if the devices belong to root for - some reason. - "; - }; - }; - - - samba = { - - enable = mkOption { - default = false; - description = " - Whether to enable the samba server. (to communicate with, and provide windows shares) - "; - }; - - }; - - - gw6c = { - - enable = mkOption { - default = false; - description = " - Whether to enable Gateway6 client (IPv6 tunnel). - "; - }; - - autorun = mkOption { - default = true; - description = " - Switch to false to create upstart-job and configuration, - but not run it automatically - "; - }; - - username = mkOption { - default = ""; - description = " - Your Gateway6 login name, if any. - "; - }; - - password = mkOption { - default = ""; - description = " - Your Gateway6 password, if any. - "; - }; - - server = mkOption { - default = "anon.freenet6.net"; - example = "broker.freenet6.net"; - description = " - Used Gateway6 server. - "; - }; - - keepAlive = mkOption { - default = "30"; - example = "2"; - description = " - Gateway6 keep-alive period. - "; - }; - - everPing = mkOption { - default = "1000000"; - example = "2"; - description = " - Gateway6 manual ping period. - "; - }; - - waitPingableBroker = mkOption { - default = true; - example = false; - description = " - Whether to wait until tunnel broker returns ICMP echo. - "; - }; - - }; - - - ircdHybrid = { - - enable = mkOption { - default = false; - description = " - Enable IRCD. - "; - }; - - serverName = mkOption { - default = "hades.arpa"; - description = " - IRCD server name. - "; - }; - - sid = mkOption { - default = "0NL"; - description = " - IRCD server unique ID in a net of servers. - "; - }; - - description = mkOption { - default = "Hybrid-7 IRC server."; - description = " - IRCD server description. - "; - }; - - rsaKey = mkOption { - default = null; - example = /root/certificates/irc.key; - description = " - IRCD server RSA key. - "; - }; - - certificate = mkOption { - default = null; - example = /root/certificates/irc.pem; - description = " - IRCD server SSL certificate. There are some limitations - read manual. - "; - }; - - adminEmail = mkOption { - default = ""; - example = ""; - description = " - IRCD server administrator e-mail. - "; - }; - - extraIPs = mkOption { - default = []; - example = ["127.0.0.1"]; - description = " - Extra IP's to bind. - "; - }; - - extraPort = mkOption { - default = "7117"; - description = " - Extra port to avoid filtering. - "; - }; - - }; - - - xfs = { - - enable = mkOption { - default = false; - description = " - Whether to enable the X Font Server. - "; - }; - - }; - - - mysql = { - enable = mkOption { - default = false; - description = " - Whether to enable the MySQL server. - "; - }; - - port = mkOption { - default = "3306"; - description = "Port of MySQL"; - }; - - user = mkOption { - default = "mysql"; - description = "User account under which MySQL runs"; - }; - - dataDir = mkOption { - default = "/var/mysql"; - description = "Location where MySQL stores its table files"; - }; - - logError = mkOption { - default = "/var/log/mysql_err.log"; - description = "Location of the MySQL error logfile"; - }; - - pidDir = mkOption { - default = "/var/run/mysql"; - description = "Location of the file which stores the PID of the MySQL server"; - }; - }; - - - postgresql = { - enable = mkOption { - default = false; - description = " - Whether to run PostgreSQL. - "; - }; - port = mkOption { - default = "5432"; - description = " - Port for PostgreSQL. - "; - }; - logDir = mkOption { - default = "/var/log/postgresql"; - description = " - Log directory for PostgreSQL. - "; - }; - dataDir = mkOption { - default = "/var/db/postgresql"; - description = " - Data directory for PostgreSQL. - "; - }; - subServices = mkOption { - default = []; - description = " - Subservices list. As it is already implememnted, - here is an interface... - "; - }; - authentication = mkOption { - default = '' - # Generated file; do not edit! - local all all ident sameuser - host all all 127.0.0.1/32 md5 - host all all ::1/128 md5 - ''; - description = " - Hosts (except localhost), who you allow to connect. - "; - }; - allowedHosts = mkOption { - default = []; - description = " - Hosts (except localhost), who you allow to connect. - "; - }; - authMethod = mkOption { - default = " ident sameuser "; - description = " - How to authorize users. - Note: ident needs absolute trust to all allowed client hosts."; - }; - }; - - - openfire = { - enable = mkOption { - default = false; - description = " - Whether to enable OpenFire XMPP server. - "; - }; - usePostgreSQL = mkOption { - default = true; - description = " - Whether you use PostgreSQL service for your storage back-end. - "; - }; - }; - - - postfix = { - enable = mkOption { - default = false; - description =" - Whether to run the Postfix mail server. - "; - }; - user = mkOption { - default = "postfix"; - description = " - How to call postfix user (must be used only for postfix). - "; - }; - group = mkOption { - default = "postfix"; - description = " - How to call postfix group (must be used only for postfix). - "; - }; - setgidGroup = mkOption { - default = "postdrop"; - description = " - How to call postfix setgid group (for postdrop). Should - be uniquely used group. - "; - }; - networks = mkOption { - default = null; - example = ["192.168.0.1/24"]; - description = " - Net masks for trusted - allowed to relay mail to third parties - - hosts. Leave empty to use mynetworks_style configuration or use - default (localhost-only). - "; - }; - networksStyle = mkOption { - default = ""; - description = " - Name of standard way of trusted network specification to use, - leave blank if you specify it explicitly or if you want to use - default (localhost-only). - "; - }; - hostname = mkOption { - default = ""; - description =" - Hostname to use. Leave blank to use just the hostname of machine. - It should be FQDN. - "; - }; - domain = mkOption { - default = ""; - description =" - Domain to use. Leave blank to use hostname minus first component. - "; - }; - origin = mkOption { - default = ""; - description =" - Origin to use in outgoing e-mail. Leave blank to use hostname. - "; - }; - destination = mkOption { - default = null; - example = ["localhost"]; - description = " - Full (!) list of domains we deliver locally. Leave blank for - acceptable Postfix default. - "; - }; - relayDomains = mkOption { - default = null; - example = ["localdomain"]; - description = " - List of domains we agree to relay to. Default is the same as - destination. - "; - }; - relayHost = mkOption { - default = ""; - description = " - Mail relay for outbound mail. - "; - }; - lookupMX = mkOption { - default = false; - description = " - Whether relay specified is just domain whose MX must be used. - "; - }; - postmasterAlias = mkOption { - default = "root"; - description = " - Who should receive postmaster e-mail. - "; - }; - rootAlias = mkOption { - default = ""; - description = " - Who should receive root e-mail. Blank for no redirection. - "; - }; - extraAliases = mkOption { - default = ""; - description = " - Additional entries to put verbatim into aliases file. - "; - }; - - sslCert = mkOption { - default = ""; - description = " - SSL certificate to use. - "; - }; - sslCACert = mkOption { - default = ""; - description = " - SSL certificate of CA. - "; - }; - sslKey = mkOption { - default = ""; - description =" - SSL key to use. - "; - }; - - recipientDelimiter = mkOption { - default = ""; - example = "+"; - description = " - Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test - "; - }; - - }; - - dovecot = { - enable = mkOption { - default = false; - description = "Whether to enable dovecot POP3/IMAP server."; - }; - - user = mkOption { - default = "dovecot"; - description = "dovecot user name"; - }; - group = mkOption { - default = "dovecot"; - description = "dovecot group name"; - }; - - sslServerCert = mkOption { - default = ""; - description = "Server certificate"; - }; - sslCACert = mkOption { - default = ""; - description = "CA certificate used by server certificate"; - }; - sslServerKey = mkOption { - default = ""; - description = "Server key"; - }; - }; - - bind = { - enable = mkOption { - default = false; - description = " - Whether to enable BIND domain name server. - "; - }; - cacheNetworks = mkOption { - default = ["127.0.0.0/24"]; - description = " - What networks are allowed to use us as a resolver. - "; - }; - blockedNetworks = mkOption { - default = []; - description = " - What networks are just blocked. - "; - }; - zones = mkOption { - default = []; - description = " - List of zones we claim authority over. - master=false means slave server; slaves means addresses - who may request zone transfer. - "; - example = [{ - name = "example.com"; - master = false; - file = "/var/dns/example.com"; - masters = ["192.168.0.1"]; - slaves = []; - }]; - }; - }; - - }; - - installer = { - - nixpkgsURL = mkOption { - default = ""; - example = http://nixos.org/releases/nix/nixpkgs-0.11pre7577; - description = " - URL of the Nixpkgs distribution to use when building the - installation CD. - "; - }; - - repos = { - nixos = mkOption { - default = [ { type = "svn"; } ]; - example = [ { type = "svn"; url = "https://svn.nixos.org/repos/nix/nixos/branches/stdenv-updates"; target = "/etc/nixos/nixos-stdenv-updates"; } - { type = "git"; initialize = ''git clone git://mawercer.de/nixos $target''; update = "git pull origin"; target = "/etc/nixos/nixos-git"; } - ]; - description = '' - The NixOS repository from which the system will be built. - nixos-checkout will update all working - copies of the given repositories, - nixos-rebuild will use the first item - which has the attribute default = true - falling back to the first item. The type defines the - repository tool added to the path. It also defines a "valid" - repository. If the target directory already exists and it's - not valid it will be moved to the backup location - dir-date. - For svn the default target and repositories are - /etc/nixos/nixos and - https://svn.nixos.org/repos/nix/nixos/trunk. - For git repositories update is called after initialization - when the repo is initialized. The initialize code is run - from working directory dirname - target and should create the - directory - dir. (git - clone url nixos/nixpkgs/services should do) For - the executables used see . - ''; - }; - - nixpkgs = mkOption { - default = [ { type = "svn"; } ]; - description = "same as "; - }; - - services = mkOption { - default = [ { type = "svn"; } ]; - description = "same as "; - }; - }; - - repoTypes = mkOption { - default = { - svn = { valid = "[ -d .svn ]"; env = [ pkgs.coreutils pkgs.subversion ]; }; - git = { valid = "[ -d .git ]"; env = [ pkgs.coreutils pkgs.git pkgs.gnused /* FIXME: use full path to sed in nix-pull */ ]; }; - }; - description = '' - Defines, for each supported version control system - (e.g. git), the dependencies for the - mechanism, as well as a test used to determine whether a - directory is a checkout created by that version control - system. - ''; - }; - - manifests = mkOption { - default = [http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST]; - example = - [ http://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable/MANIFEST - http://nixos.org/releases/nixpkgs/channels/nixpkgs-stable/MANIFEST - ]; - description = " - URLs of manifests to be downloaded when you run - nixos-rebuild to speed up builds. - "; - }; - - }; - - - nix = { - - maxJobs = mkOption { - default = 1; - example = 2; - description = " - This option defines the maximum number of jobs that Nix will try - to build in parallel. The default is 1. You should generally - set it to the number of CPUs in your system (e.g., 2 on a Athlon - 64 X2). - "; - }; - - useChroot = mkOption { - default = false; - example = true; - description = " - If set, Nix will perform builds in a chroot-environment that it - will set up automatically for each build. This prevents - impurities in builds by disallowing access to dependencies - outside of the Nix store. - "; - }; - - extraOptions = mkOption { - default = ""; - example = " - gc-keep-outputs = true - gc-keep-derivations = true - "; - description = " - This option allows to append lines to nix.conf. - "; - }; - - distributedBuilds = mkOption { - default = false; - description = " - Whether to distribute builds to the machines listed in - . - "; - }; - - buildMachines = mkOption { - example = [ - { hostName = "voila.labs.cs.uu.nl"; - sshUser = "nix"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "powerpc-darwin"; - maxJobs = 1; - } - { hostName = "linux64.example.org"; - sshUser = "buildfarm"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "x86_64-linux"; - maxJobs = 2; - } - ]; - description = " - This option lists the machines to be used if distributed - builds are enabled (see - ). Nix will perform - derivations on those machines via SSh by copying the inputs to - the Nix store on the remote machine, starting the build, then - copying the output back to the local Nix store. Each element - of the list should be an attribute set containing the - machine's host name (hostname), the user - name to be used for the SSH connection - (sshUser), the Nix system type - (system, e.g., - \"i686-linux\"), the maximum number of jobs - to be run in parallel on that machine - (maxJobs), and the path to the SSH private - key to be used to connect (sshKey). The - SSH private key should not have a passphrase, and the - corresponding public key should be added to - ~sshUser/authorized_keys - on the remote machine. - "; - }; - - proxy = mkOption { - default = ""; - description = " - This option specifies the proxy to use for fetchurl. The real effect - is just exporting http_proxy, https_proxy and ftp_proxy with that - value. - "; - example = "http://127.0.0.1:3128"; - }; - - # Environment variables for running Nix. - envVars = mkOption { - internal = true; - default = ""; - description = " - Define the environment variables used by nix to - "; - - merge = pkgs.lib.mergeStringOption; - - # other option should be used to define the content instead of using - # the apply function. - apply = conf: '' - export NIX_CONF_DIR=/nix/etc/nix - - # Enable the copy-from-other-stores substituter, which allows builds - # to be sped up by copying build results from remote Nix stores. To - # do this, mount the remote file system on a subdirectory of - # /var/run/nix/remote-stores. - export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix - - '' + # */ - (if config.nix.distributedBuilds then - '' - export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl - export NIX_REMOTE_SYSTEMS=/etc/nix.machines - export NIX_CURRENT_LOAD=/var/run/nix/current-load - '' - else "") - + - (if config.nix.proxy != "" then - '' - export http_proxy=${config.nix.proxy} - export https_proxy=${config.nix.proxy} - export ftp_proxy=${config.nix.proxy} - '' - else "") - + conf; - }; - }; - - - security = { - - setuidPrograms = mkOption { - default = [ - "passwd" "su" "crontab" "ping" "ping6" - "fusermount" "wodim" "cdrdao" "growisofs" - ]; - description = " - Only the programs from system path listed her will be made setuid root - (through a wrapper program). It's better to set - . - "; - }; - - extraSetuidPrograms = mkOption { - default = []; - example = ["fusermount"]; - description = " - This option lists additional programs that must be made setuid - root. - "; - }; - - setuidOwners = mkOption { - default = []; - example = [{ - program = "sendmail"; - owner = "nodody"; - group = "postdrop"; - setuid = false; - setgid = true; - }]; - description = '' - List of non-trivial setuid programs from system path, like Postfix sendmail. Default - should probably be nobody:nogroup:false:false - if you are bothering - doing anything with a setuid program, "root.root u+s g-s" is not what - you are aiming at.. - ''; - }; - - seccureKeys = { - public = mkOption { - default = /var/elliptic-keys/public; - description = " - Public key. Make it path argument, so it is copied into store and - hashed. - - The key is used to encrypt Gateway 6 configuration in store, as it - contains a password for external service. Unfortunately, - derivation file should be protected by other means. For example, - nix-http-export.cgi will happily export any non-derivation path, - but not a derivation. - "; - }; - private = mkOption { - default = "/var/elliptic-keys/private"; - description = " - Private key. Make it string argument, so it is not copied into store. - "; - }; - }; - - }; - - - users = { - - ldap = { - - enable = mkOption { - default = false; - description = " - Whether to enable authentication against an LDAP server. - "; - }; - - server = mkOption { - example = "ldap://ldap.example.org/"; - description = " - The URL of the LDAP server. - "; - }; - - base = mkOption { - example = "dc=example,dc=org"; - description = " - The distinguished name of the search base. - "; - }; - - useTLS = mkOption { - default = false; - description = " - If enabled, use TLS (encryption) over an LDAP (port 389) - connection. The alternative is to specify an LDAPS server (port - 636) in or to forego - security. - "; - }; - - }; - - }; - - - i18n = { - - defaultLocale = mkOption { - default = "en_US.UTF-8"; - example = "nl_NL.UTF-8"; - description = " - The default locale. It determines the language for program - messages, the format for dates and times, sort order, and so on. - It also determines the character set, such as UTF-8. - "; - }; - - consoleFont = mkOption { - default = "lat9w-16"; - example = "LatArCyrHeb-16"; - description = " - The font used for the virtual consoles. Leave empty to use - whatever the setfont program considers the - default font. - "; - }; - - consoleKeyMap = mkOption { - default = "us"; - example = "fr"; - description = " - The keyboard mapping table for the virtual consoles. - "; - }; - - }; - - - environment = { - - pathsToLink = mkOption { - default = ["/bin" "/sbin" "/lib" "/share" "/man" "/info" "/etc"]; - example = ["/"]; - description = " - Lists directories to be symlinked in `/var/run/current-system/sw'. - "; - }; - - cleanStart = mkOption { - default = false; - example = true; - description = " - There are some times when you want really small system for specific - purpose and do not want default package list. Setting - cleanStart to true allows you - to create a system with empty path - only extraPackages will be - included. - "; - }; - - extraPackages = mkOption { - default = []; - example = [pkgs.firefox pkgs.thunderbird]; - description = " - This option allows you to add additional packages to the system - path. These packages are automatically available to all users, - and they are automatically updated every time you rebuild the - system configuration. (The latter is the main difference with - installing them in the default profile, - /nix/var/nix/profiles/default. The value - of this option must be a function that returns a list of - packages. The function will be called with the Nix Packages - collection as its argument for convenience. - "; - }; - - nix = mkOption { - default = pkgs.nixUnstable; - example = pkgs.nixCustomFun /root/nix.tar.gz; - merge = mergeOneOption; - description = " - Use non-default Nix easily. Be careful, though, not to break everything. - "; - }; - - checkConfigurationOptions = mkOption { - default = true; - example = false; - description = " - If all configuration options must be checked. Non-existing options fail build. - "; - }; - - unixODBCDrivers = mkOption { - default = pkgs : []; - example = "pkgs : map (x : x.ini) (with pkgs.unixODBCDrivers; [ mysql psql psqlng ] )"; - description = "specifies unix odbc drivers to be registered at /etc/odbcinst.ini"; - }; - - }; - - - powerManagement = { - - enable = mkOption { - default = false; - description = " - Whether to enable power management. - "; - }; - - }; - - nesting = { children = mkOption { default = []; @@ -2230,12 +387,38 @@ in (import ../system/activate-configuration.nix) (import ../upstart-jobs/default.nix) + (import ../upstart-jobs/acpid.nix) # ACPI daemon + + (import ../system/unix-odbc-drivers.nix) + + (import ../upstart-jobs/klogd.nix) + + (import ../upstart-jobs/lvm.nix) # Makes LVM logical volumes available. + + (import ../upstart-jobs/swraid.nix) # Activate software RAID arrays. + + (import ../upstart-jobs/filesystems.nix) # Mount file systems. + + (import ../upstart-jobs/swap.nix) + (import ../upstart-jobs/network-interfaces.nix) + (import ../upstart-jobs/nscd.nix) # Name service cache daemon. + (import ../upstart-jobs/maintenance-shell.nix) # Handles the maintenance/stalled event (single-user shell). + (import ../upstart-jobs/ctrl-alt-delete.nix) # Ctrl-alt-delete action. + (import ../upstart-jobs/halt.nix) # FIXME (assertion) # Handles the reboot/halt events. + (import ../upstart-jobs/ifplugd.nix) # ifplugd daemon for monitoring Ethernet cables. + + # security (import ../system/sudo.nix) + # i18n + (import ../system/i18n.nix) + # environment (import ../etc/default.nix) + (import ../system/nixos-environment.nix) + # users (import ../system/users-groups.nix) @@ -2245,6 +428,9 @@ in # hardware (import ../upstart-jobs/pcmcia.nix) + # security + (import ../system/nixos-security.nix) + # services (import ../upstart-jobs/avahi-daemon.nix) (import ../upstart-jobs/atd.nix) @@ -2263,6 +449,46 @@ in (import ../upstart-jobs/rogue.nix) (import ../upstart-jobs/guest-users.nix) (import ../upstart-jobs/pulseaudio.nix) + (import ../upstart-jobs/kbd.nix) + (import ../upstart-jobs/gw6c.nix) # Gateway6 + (import ../upstart-jobs/syslogd.nix) + (import ../upstart-jobs/dhcpd.nix) + (import ../upstart-jobs/sshd.nix) + (import ../upstart-jobs/lshd.nix) # GNU lshd SSH2 deamon (TODO: does neither start nor generate seed file ?) + (import ../upstart-jobs/ntpd.nix) + (import ../upstart-jobs/portmap.nix) + (import ../upstart-jobs/bitlbee.nix) + (import ../upstart-jobs/gnunet.nix) + (import ../upstart-jobs/ejabberd.nix) # untested, dosen't compile on x86_64-linux + (import ../upstart-jobs/jboss.nix) + (import ../upstart-jobs/tomcat.nix) # untested, too lazy to get that jdk + (import ../upstart-jobs/httpd.nix) # Apache httpd (probably this can be removed ?) + (import ../upstart-jobs/apache-httpd) # Apache httpd (new style). + (import ../upstart-jobs/vsftpd.nix) + (import ../upstart-jobs/cupsd.nix) # CUPS printing daemon + (import ../upstart-jobs/udev.nix) # The udev daemon creates devices nodes and runs programs when hardware events occur. + (import ../upstart-jobs/samba.nix) # TODO: doesn't start here (?) + (import ../upstart-jobs/ircd-hybrid.nix) # TODO: doesn't compile on x86_64-linux, can't test + (import ../upstart-jobs/xfs.nix) # FIXME (assertion) + (import ../upstart-jobs/mysql.nix) + (import ../upstart-jobs/postgresql.nix) + (import ../upstart-jobs/openfire.nix) # FIXME (assertion) + (import ../upstart-jobs/postfix.nix) + (import ../upstart-jobs/dovecot.nix) + (import ../upstart-jobs/bind.nix) + + (import ../upstart-jobs/mingetty.nix) # The terminals on ttyX. + (import ../upstart-jobs/tty-backgrounds.nix) #FIXME (assertion) + + # nix + (import ../upstart-jobs/nix.nix) # nix options and daemon + (import ../system/nixos-installer.nix) + + + #users + (import ../upstart-jobs/ldap) + + # fonts (import ../system/fonts.nix) diff --git a/system/unix-odbc-drivers.nix b/system/unix-odbc-drivers.nix new file mode 100644 index 000000000000..7df87db8577c --- /dev/null +++ b/system/unix-odbc-drivers.nix @@ -0,0 +1,43 @@ +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + environment = { + unixODBCDrivers = mkOption { + default = []; + example = "map (x : x.ini) (with pkgs.unixODBCDrivers; [ mysql psql psqlng ] )"; + description = '' + specifies unix odbc drivers to be registered at /etc/odbcinst.ini. + Maybe you also want to add pkgs.unixODBC to the system path to get a + command line client t connnect to odbc databases. + ''; + }; + }; + }; +in + +###### implementation + + +# unixODBC drivers (this solution is not perfect.. Because the user has to +# ask the admin to add a driver.. but it's simple and works + +mkIf (config.environment.unixODBCDrivers != []) { + + require = [ + options + ]; + + environment = { + etc = [ + { source = + let inis = config.environment.unixODBCDrivers; + in pkgs.writeText "odbcinst.ini" (pkgs.lib.concatStringsSep "\n" inis); + target = "odbcinst.ini"; + } + ]; + }; +} diff --git a/system/users-groups.nix b/system/users-groups.nix index f1bd59a2f367..5dec1f1d1b3c 100644 --- a/system/users-groups.nix +++ b/system/users-groups.nix @@ -143,6 +143,9 @@ let inherit (pkgs.stringsWithDeps) FullDepEntry; activateLib = config.system.activationScripts.lib; + + # keep this extra file so that cat can be used to pass special chars such as "`" which is used in the avahi daemon + usersFile = pkgs.writeText "users" (concatStringsSep "\n" (map serializedUser users)); in { @@ -157,7 +160,7 @@ in activationScripts = { users = FullDepEntry '' - while true; do + cat ${usersFile} | while true; do read name || break read description read uid @@ -198,9 +201,7 @@ in ''${home:+--home "$home"} \ --shell "$shell" fi - done < /dev/null 2>&1 \ + ../default.nix -A system +done +set +xe diff --git a/upstart-jobs/acpid.nix b/upstart-jobs/acpid.nix index e2eb702bcd43..5ab724b431c4 100644 --- a/upstart-jobs/acpid.nix +++ b/upstart-jobs/acpid.nix @@ -1,5 +1,22 @@ {pkgs, config, ...}: +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + powerManagement = { + + enable = mkOption { + default = false; + description = "Whether to enable power management (ACPI daemon)"; + }; + }; + }; +in + +###### implementation + let acpiConfDir = pkgs.runCommand "acpi-events" {} @@ -17,9 +34,7 @@ let in pkgs.lib.concatMapStrings f events } ''; - - events = [powerEvent lidEvent acEvent]; - + # Called when the power button is pressed. powerEvent = { name = "power-button"; @@ -29,7 +44,7 @@ let #! ${pkgs.bash}/bin/sh ''; }; - + # Called when the laptop lid is opened/closed. lidEvent = { name = "lid"; @@ -47,7 +62,7 @@ let fi ''; }; - + # Called when the AC power is connected or disconnected. acEvent = { name = "ac-power"; @@ -64,20 +79,27 @@ let ''; }; + events = [powerEvent lidEvent acEvent]; + in -{ - name = "acpid"; - - extraPath = [pkgs.acpid]; - - job = '' - description "ACPI daemon" +mkIf config.powerManagement.enable { + require = [ + options + ]; - start on udev - stop on shutdown + services = { + extraJobs = [{ + name = "acpid"; - respawn ${pkgs.acpid}/sbin/acpid --foreground --confdir ${acpiConfDir} - ''; - + job = '' + description "ACPI daemon" + + start on udev + stop on shutdown + + respawn ${pkgs.acpid}/sbin/acpid --foreground --confdir ${acpiConfDir} + ''; + }]; + }; } diff --git a/upstart-jobs/apache-httpd/default.nix b/upstart-jobs/apache-httpd/default.nix index ee15dc06f016..aab5d331d10c 100644 --- a/upstart-jobs/apache-httpd/default.nix +++ b/upstart-jobs/apache-httpd/default.nix @@ -1,6 +1,209 @@ -{config, pkgs}: +{pkgs, config, ...}: +###### interface let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + httpd = { + + enable = mkOption { + default = false; + description = " + Whether to enable the Apache httpd server. + "; + }; + + experimental = mkOption { + default = false; + description = " + Whether to use the new-style Apache configuration. + "; + }; + + extraConfig = mkOption { + default = ""; + description = " + These configuration lines will be passed verbatim to the apache config + "; + }; + + extraModules = mkOption { + default = []; + example = [ "proxy_connect" { name = "php5_module"; path = "${pkgs.php}/modules/libphp5.so"; } ]; + description = '' + Specifies additional Apache modules. These can be specified + as a string in the case of modules distributed with Apache, + or as an attribute set specifying the + name and path of the + module. + ''; + }; + + logPerVirtualHost = mkOption { + default = false; + description = " + If enabled, each virtual host gets its own + access_log and + error_log, namely suffixed by the + of the virtual host. + "; + }; + + user = mkOption { + default = "wwwrun"; + description = " + User account under which httpd runs. The account is created + automatically if it doesn't exist. + "; + }; + + group = mkOption { + default = "wwwrun"; + description = " + Group under which httpd runs. The account is created + automatically if it doesn't exist. + "; + }; + + logDir = mkOption { + default = "/var/log/httpd"; + description = " + Directory for Apache's log files. It is created automatically. + "; + }; + + stateDir = mkOption { + default = "/var/run/httpd"; + description = " + Directory for Apache's transient runtime state (such as PID + files). It is created automatically. Note that the default, + /var/run/httpd, is deleted at boot time. + "; + }; + + mod_php = mkOption { + default = false; + description = "Whether to enable the PHP module."; + }; + + mod_jk = { + enable = mkOption { + default = false; + description = "Whether to enable the Apache Tomcat connector."; + }; + + applicationMappings = mkOption { + default = []; + description = "List of Java webapplications that should be mapped to the servlet container (Tomcat/JBoss)"; + }; + }; + + virtualHosts = mkOption { + default = []; + example = [ + { hostName = "foo"; + documentRoot = "/data/webroot-foo"; + } + { hostName = "bar"; + documentRoot = "/data/webroot-bar"; + } + ]; + description = '' + Specification of the virtual hosts served by Apache. Each + element should be an attribute set specifying the + configuration of the virtual host. The available options + are the non-global options permissible for the main host. + ''; + }; + + subservices = { + + # !!! remove this + subversion = { + + enable = mkOption { + default = false; + description = " + Whether to enable the Subversion subservice in the webserver. + "; + }; + + notificationSender = mkOption { + default = "svn-server@example.org"; + example = "svn-server@example.org"; + description = " + The email address used in the Sender field of commit + notification messages sent by the Subversion subservice. + "; + }; + + userCreationDomain = mkOption { + default = "example.org"; + example = "example.org"; + description = " + The domain from which user creation is allowed. A client can + only create a new user account if its IP address resolves to + this domain. + "; + }; + + autoVersioning = mkOption { + default = false; + description = " + Whether you want the Subversion subservice to support + auto-versioning, which enables Subversion repositories to be + mounted as read/writable file systems on operating systems that + support WebDAV. + "; + }; + + dataDir = mkOption { + default = "/no/such/path/exists"; + description = " + Place to put SVN repository. + "; + }; + + organization = { + + name = mkOption { + default = null; + description = " + Name of the organization hosting the Subversion service. + "; + }; + + url = mkOption { + default = null; + description = " + URL of the website of the organization hosting the Subversion service. + "; + }; + + logo = mkOption { + default = null; + description = " + Logo the organization hosting the Subversion service. + "; + }; + + }; + + }; + + }; + } // # Include the options shared between the main server and virtual hosts. + (import ../../upstart-jobs/apache-httpd/per-server-options.nix { + inherit mkOption; + forMainServer = true; + }); + }; + }; + + +###### implementation mainCfg = config.services.httpd; @@ -361,65 +564,75 @@ let in -{ - name = "httpd"; - - users = [ - { name = mainCfg.user; - description = "Apache httpd user"; - } +mkIf (config.services.httpd.enable && config.services.httpd.experimental) { + require = [ + options ]; - groups = [ - { name = mainCfg.group; - } - ]; + users = { + extraUsers = [ + { name = mainCfg.user; + description = "Apache httpd user"; + } + ]; + extraGroups = [ + { name = mainCfg.group; + } + ]; + }; - extraPath = [httpd] ++ concatMap (svc: svc.extraPath) allSubservices; + services = { + extraJobs = [{ + name = "httpd"; - # Statically verify the syntactic correctness of the generated - # httpd.conf. !!! this is impure! It doesn't just check for - # syntax, but also whether the Apache user/group exist, whether SSL - # keys exist, etc. - buildHook = '' - echo - echo '=== Checking the generated Apache configuration file ===' - ${httpd}/bin/httpd -f ${httpdConf} -t || true - ''; + extraPath = [httpd] ++ concatMap (svc: svc.extraPath) allSubservices; - job = '' - description "Apache HTTPD" + # Statically verify the syntactic correctness of the generated + # httpd.conf. !!! this is impure! It doesn't just check for + # syntax, but also whether the Apache user/group exist, whether SSL + # keys exist, etc. + buildHook = '' + echo + echo '=== Checking the generated Apache configuration file ===' + ${httpd}/bin/httpd -f ${httpdConf} -t || true + ''; - start on ${startingDependency}/started - stop on shutdown + job = '' + description "Apache HTTPD" - start script - mkdir -m 0700 -p ${mainCfg.stateDir} - mkdir -m 0700 -p ${mainCfg.logDir} + start on ${startingDependency}/started + stop on shutdown - # Get rid of old semaphores. These tend to accumulate across - # server restarts, eventually preventing it from restarting - # succesfully. - for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${mainCfg.user} ' | cut -f2 -d ' '); do - ${pkgs.utillinux}/bin/ipcrm -s $i - done + start script + mkdir -m 0700 -p ${mainCfg.stateDir} + mkdir -m 0700 -p ${mainCfg.logDir} - # Run the startup hooks for the subservices. - for i in ${toString (map (svn: svn.startupScript) allSubservices)}; do - echo Running Apache startup hook $i... - $i - done - end script + # Get rid of old semaphores. These tend to accumulate across + # server restarts, eventually preventing it from restarting + # succesfully. + for i in $(${pkgs.utillinux}/bin/ipcs -s | grep ' ${mainCfg.user} ' | cut -f2 -d ' '); do + ${pkgs.utillinux}/bin/ipcrm -s $i + done - ${ - let f = {name, value}: "env ${name}=${value}\n"; - in concatMapStrings f (pkgs.lib.concatMap (svc: svc.globalEnvVars) allSubservices) - } + # Run the startup hooks for the subservices. + for i in ${toString (map (svn: svn.startupScript) allSubservices)}; do + echo Running Apache startup hook $i... + $i + done + end script - env PATH=${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.lib.concatStringsSep ":" (pkgs.lib.concatMap (svc: svc.extraServerPath) allSubservices)} + ${ + let f = {name, value}: "env ${name}=${value}\n"; + in concatMapStrings f (pkgs.lib.concatMap (svc: svc.globalEnvVars) allSubservices) + } - respawn ${httpd}/bin/httpd -f ${httpdConf} -DNO_DETACH - ''; + env PATH=${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.lib.concatStringsSep ":" (pkgs.lib.concatMap (svc: svc.extraServerPath) allSubservices)} + respawn ${httpd}/bin/httpd -f ${httpdConf} -DNO_DETACH + ''; + + }]; + }; } + diff --git a/upstart-jobs/bind.nix b/upstart-jobs/bind.nix index f645abc9340e..d216987e573d 100644 --- a/upstart-jobs/bind.nix +++ b/upstart-jobs/bind.nix @@ -1,4 +1,52 @@ -{config, pkgs}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + bind = { + enable = mkOption { + default = false; + description = " + Whether to enable BIND domain name server. + "; + }; + cacheNetworks = mkOption { + default = ["127.0.0.0/24"]; + description = " + What networks are allowed to use us as a resolver. + "; + }; + blockedNetworks = mkOption { + default = []; + description = " + What networks are just blocked. + "; + }; + zones = mkOption { + default = []; + description = " + List of zones we claim authority over. + master=false means slave server; slaves means addresses + who may request zone transfer. + "; + example = [{ + name = "example.com"; + master = false; + file = "/var/dns/example.com"; + masters = ["192.168.0.1"]; + slaves = []; + }]; + }; + }; + }; + }; +in + +###### implementation + let startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; cfg = config.services.bind; @@ -52,15 +100,24 @@ let confFile = pkgs.writeText "named.conf" namedConf; in -{ - name = "bind"; - job = '' - description "BIND name server job" - start script - ${pkgs.coreutils}/bin/mkdir -p /var/run/named - end script +mkIf config.services.bind.enable { + require = [ + options + ]; - respawn ${pkgs.bind}/sbin/named -c ${confFile} -f - ''; -} + services = { + extraJobs = [{ + name = "bind"; + job = '' + description "BIND name server job" + + start script + ${pkgs.coreutils}/bin/mkdir -p /var/run/named + end script + + respawn ${pkgs.bind}/sbin/named -c ${confFile} -f + ''; + }]; + }; +} diff --git a/upstart-jobs/bitlbee.nix b/upstart-jobs/bitlbee.nix index d9956230aa07..a1cc1a878613 100644 --- a/upstart-jobs/bitlbee.nix +++ b/upstart-jobs/bitlbee.nix @@ -1,40 +1,93 @@ -args: with args; +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + bitlbee = { + + enable = mkOption { + default = false; + description = '' + Whether to run the BitlBee IRC to other chat network gateway. + Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat + networks via an IRC client. + ''; + }; + + interface = mkOption { + default = "127.0.0.1"; + description = '' + The interface the BitlBee deamon will be listening to. If `127.0.0.1', + only clients on the local host can connect to it; if `0.0.0.0', clients + can access it from any network interface. + ''; + }; + + portNumber = mkOption { + default = 6667; + description = '' + Number of the port BitlBee will be listening to. + ''; + }; + + }; + }; + }; +in + +###### implementation let bitlbeeUid = (import ../system/ids.nix).uids.bitlbee; + inherit (config.services.bitlbee) portNumber interface; in -{ - name = "bitlbee"; - users = [ - { name = "bitlbee"; - uid = bitlbeeUid; - description = "BitlBee user"; - home = "/var/empty"; - } - ]; - - groups = [ - { name = "bitlbee"; - gid = (import ../system/ids.nix).gids.bitlbee; - } +mkIf config.services.bitlbee.enable { + + require = [ + options ]; - job = '' -description "BitlBee IRC to other chat networks gateway" + users = { + extraUsers = [ + { name = "bitlbee"; + uid = bitlbeeUid; + description = "BitlBee user"; + home = "/var/empty"; + } + ]; + + extraGroups = [ + { name = "bitlbee"; + gid = (import ../system/ids.nix).gids.bitlbee; + } + ]; + }; -start on network-interfaces/started -stop on network-interfaces/stop + services = { + extraJobs = [{ + name = "bitlbee"; -start script - if ! test -d /var/lib/bitlbee - then - mkdir -p /var/lib/bitlbee - fi -end script + job = '' + description "BitlBee IRC to other chat networks gateway" -respawn ${bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \ - -i ${interface} -u bitlbee - ''; + start on network-interfaces/started + stop on network-interfaces/stop + + start script + if ! test -d /var/lib/bitlbee + then + mkdir -p /var/lib/bitlbee + fi + end script + + respawn ${pkgs.bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \ + -i ${interface} -u bitlbee + ''; + }]; + }; } diff --git a/upstart-jobs/ctrl-alt-delete.nix b/upstart-jobs/ctrl-alt-delete.nix index 126154bae733..6f58606b5cdd 100644 --- a/upstart-jobs/ctrl-alt-delete.nix +++ b/upstart-jobs/ctrl-alt-delete.nix @@ -1,12 +1,20 @@ -{ - name = "ctrl-alt-delete"; - - job = " -on ctrlaltdel +{pkgs, config, ...}: -script - shutdown -r now 'Ctrl-Alt-Delete pressed' -end script - "; - +###### implementation + +{ + + services = { + extraJobs = [{ + name = "ctrl-alt-delete"; + + job = '' + on ctrlaltdel + + script + shutdown -r now 'Ctrl-Alt-Delete pressed' + end script + ''; + }]; + }; } diff --git a/upstart-jobs/cupsd.nix b/upstart-jobs/cupsd.nix index ced164a13088..7f5529e6f75e 100644 --- a/upstart-jobs/cupsd.nix +++ b/upstart-jobs/cupsd.nix @@ -1,4 +1,26 @@ -{config, pkgs, modprobe}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + printing = { + + enable = mkOption { + default = false; + description = " + Whether to enable printing support through the CUPS daemon. + "; + }; + + }; + }; + }; +in + +###### implementation let @@ -7,6 +29,8 @@ let inherit (pkgs) cups; + modprobe = config.system.sbin.modprobe; + # Here we can enable additional backends, filters, etc. that are not # part of CUPS itself, e.g. the SMB backend is part of Samba. Since @@ -101,37 +125,45 @@ let in -{ - name = "cupsd"; - extraPath = [cups]; - - extraEtc = [ - # CUPS expects the following files in its ServerRoot. - { source = "${cups}/etc/cups/mime.convs"; - target = "cups/mime.convs"; - } - { source = "${cups}/etc/cups/mime.types"; - target = "cups/mime.types"; - } +mkIf config.services.pulseaudio.enable { + require = [ + options ]; - - job = '' - description "CUPS printing daemon" - start on network-interfaces/started - stop on network-interfaces/stop + services = { + extraJobs = [{ + name = "cupsd"; - start script - mkdir -m 0755 -p ${logDir} - mkdir -m 0700 -p /var/cache/cups - mkdir -m 0700 -p /var/spool/cups + extraPath = [cups]; - # Make USB printers show up. - ${modprobe}/sbin/modprobe usblp || true - end script + extraEtc = [ + # CUPS expects the following files in its ServerRoot. + { source = "${cups}/etc/cups/mime.convs"; + target = "cups/mime.convs"; + } + { source = "${cups}/etc/cups/mime.types"; + target = "cups/mime.types"; + } + ]; + + job = '' + description "CUPS printing daemon" - respawn ${cups}/sbin/cupsd -c ${cupsdConfig} -F - ''; - + start on network-interfaces/started + stop on network-interfaces/stop + + start script + mkdir -m 0755 -p ${logDir} + mkdir -m 0700 -p /var/cache/cups + mkdir -m 0700 -p /var/spool/cups + + # Make USB printers show up. + ${modprobe}/sbin/modprobe usblp || true + end script + + respawn ${cups}/sbin/cupsd -c ${cupsdConfig} -F + ''; + }]; + }; } diff --git a/upstart-jobs/default.nix b/upstart-jobs/default.nix index ea5d8fcdbe02..57f0006eb8a3 100644 --- a/upstart-jobs/default.nix +++ b/upstart-jobs/default.nix @@ -19,7 +19,7 @@ let exec sh -c "echo 'hello world' | ${pkgs.netcat}/bin/nc -l -p 9000" ''; } ]; - # should have some checks to everify the syntax + # should have some checks to verify the syntax merge = pkgs.lib.mergeListOption; description = " Additional Upstart jobs. @@ -66,373 +66,9 @@ let optional = cond: service: pkgs.lib.optional cond (makeJob service); - requiredTTYs = - config.services.mingetty.ttys - ++ config.boot.extraTTYs - ++ [config.services.syslogd.tty]; + requiredTTYs = config.requiredTTYs; - # looks for a job file foreach attr name found in services from config - # passes { thisConfig, config, pkgs } - # a job must return { options = {}; job =; } - # options is the same format as options.nix, but only contains documentation for this job - # TODO check validation - newProposalJobs = - ( - let - inherit (pkgs.lib) getAttr; - inherit (builtins) attrNames pathExists map; - services = getAttr [ "servicesProposal" ] {} config; - nameToJobs = name : ( - ( - let p = ./new-proposal + "/${name}.nix"; - p2 = ./new-proposal + "/${name}/default.nix"; - thisConfig = getAttr [ name ] {} services; - path = [name]; - args = confgiV : { - inherit config pkgs thisConfig path; - lib = pkgs.lib; - upstartHelpers = { # some useful functions - inherit configV; # the first time a error function is passed to get the option list - # the second time a function is passed getting the option for you automatically, - # either returning the default option or the user supplied value (the function apply is applied when given) - # maybe this is complicated, but easy to use (IMHO) - mkOption = pkgs.lib.mkOption; # the same function used in options.nix - autoGeneratedEtcFile = { name, commentChar ? "#", content } : - { source = pkgs.writeText name - ("${commentChar} nixos autogenerated etc file based on /etc/nixos/configuration.nix\n" + content); - target = name; - }; - }; - }; - jobFunc = if pathExists p - then import p - else if pathExists p2 then import p2 - else abort "service ${name} requested but there is no ${p}.nix or ${p}/default.nix file!"; - options = (jobFunc (args (abort "you can't use configV within options!"))).options; - errorWhere = name : "${name} of service ${builtins.toString path}"; - configV = name : if (__hasAttr name options ) then - let opt = (__getAttr name options ); # this config option description - in if (__hasAttr name thisConfig ) - then let v = (__getAttr name thisConfig); in if opt ? apply then opt.apply v else v - else if opt ? default then opt.default else abort "you need to specify the configuration option ${errorWhere name}" - else abort "unkown option ${errorWhere name}"; - checkConfig = config.environment.checkConfigurationOptions; - in # TODO: pass path to checker so it can show full path in the abort case - pkgs.checker ( (jobFunc (args configV)).jobs ) - checkConfig - options - thisConfig - - )); - in pkgs.lib.concatLists ( map nameToJobs (attrNames services))); - - jobs = map makeJob - (newProposalJobs ++ [ - - # Syslogd. - (import ../upstart-jobs/syslogd.nix { - inherit (pkgs) sysklogd writeText; - inherit config; - }) - - # Klogd. - (import ../upstart-jobs/klogd.nix { - inherit (pkgs) sysklogd writeText; - inherit config; - }) - - # The udev daemon creates devices nodes and runs programs when - # hardware events occur. - (import ../upstart-jobs/udev.nix { - inherit modprobe config; - inherit (pkgs) stdenv writeText substituteAll udev procps; - inherit (pkgs.lib) cleanSource; - firmwareDirs = config.services.udev.addFirmware; - extraUdevPkgs = config.services.udev.addUdevPkgs; - }) - - # Makes LVM logical volumes available. - (import ../upstart-jobs/lvm.nix { - inherit modprobe; - inherit (pkgs) lvm2 devicemapper; - }) - - # Activate software RAID arrays. - (import ../upstart-jobs/swraid.nix { - inherit modprobe; - inherit (pkgs) mdadm; - }) - - # Mount file systems. - (import ../upstart-jobs/filesystems.nix { - inherit mount; - inherit (pkgs) utillinux e2fsprogs; - fileSystems = config.fileSystems; - }) - - # Swapping. - (import ../upstart-jobs/swap.nix { - inherit (pkgs) utillinux lib; - swapDevices = config.swapDevices; - }) - - # Network interfaces. - (import ../upstart-jobs/network-interfaces.nix { - inherit modprobe config; - inherit (pkgs) nettools wirelesstools bash writeText; - }) - - # Nix daemon - required for multi-user Nix. - (import ../upstart-jobs/nix-daemon.nix { - inherit config pkgs nix nixEnvVars; - }) - - # Name service cache daemon. - (import ../upstart-jobs/nscd.nix { - inherit (pkgs) glibc; - inherit nssModulesPath; - }) - - # Console font and keyboard maps. - (import ../upstart-jobs/kbd.nix { - inherit (pkgs) glibc kbd gzip; - ttyNumbers = requiredTTYs; - defaultLocale = config.i18n.defaultLocale; - consoleFont = config.i18n.consoleFont; - consoleKeyMap = config.i18n.consoleKeyMap; - }) - - # Handles the maintenance/stalled event (single-user shell). - (import ../upstart-jobs/maintenance-shell.nix { - inherit (pkgs) bash; - }) - - # Ctrl-alt-delete action. - (import ../upstart-jobs/ctrl-alt-delete.nix) - - ]) - - # ifplugd daemon for monitoring Ethernet cables. - ++ optional config.networking.interfaceMonitor.enable - (import ../upstart-jobs/ifplugd.nix { - inherit (pkgs) ifplugd writeScript bash; - inherit config; - }) - - # DHCP server. - ++ optional config.services.dhcpd.enable - (import ../upstart-jobs/dhcpd.nix { - inherit pkgs config; - }) - - # SSH daemon. - ++ optional config.services.sshd.enable - (import ../upstart-jobs/sshd.nix { - inherit (pkgs) writeText openssh glibc; - inherit (pkgs.xorg) xauth; - inherit nssModulesPath; - inherit (config.services.sshd) forwardX11 allowSFTP permitRootLogin gatewayPorts; - }) - - # GNU lshd SSH2 deamon. - ++ optional config.services.lshd.enable - (import ../upstart-jobs/lshd.nix { - inherit (pkgs) lib; - inherit (pkgs) lsh; - inherit (pkgs.xorg) xauth; - inherit nssModulesPath; - lshdConfig = config.services.lshd; - }) - - # GNUnet daemon. - ++ optional config.services.gnunet.enable - (import ../upstart-jobs/gnunet.nix { - inherit (pkgs) gnunet lib writeText; - gnunetConfig = config.services.gnunet; - }) - - # NTP daemon. - ++ optional config.services.ntp.enable - (import ../upstart-jobs/ntpd.nix { - inherit modprobe; - inherit (pkgs) ntp glibc writeText; - servers = config.services.ntp.servers; - }) - - # portmap daemon. - ++ optional config.services.portmap.enable - (import ../upstart-jobs/portmap.nix { - inherit (pkgs) makePortmap; - }) - - # Apache httpd. - ++ optional (config.services.httpd.enable && !config.services.httpd.experimental) - (import ../upstart-jobs/httpd.nix { - inherit config pkgs; - inherit (pkgs) glibc; - extraConfig = pkgs.lib.concatStringsSep "\n" - (map (job: job.extraHttpdConfig) jobs); - }) - - # Apache httpd (new style). - ++ optional (config.services.httpd.enable && config.services.httpd.experimental) - (import ../upstart-jobs/apache-httpd { - inherit config pkgs; - }) - - # MySQL server - ++ optional config.services.mysql.enable - (import ../upstart-jobs/mysql.nix { - inherit config pkgs; - }) - - # Postgres SQL server - ++ optional config.services.postgresql.enable - (import ../upstart-jobs/postgresql.nix { - inherit config pkgs; - }) - - # EJabberd service - ++ optional config.services.ejabberd.enable - (import ../upstart-jobs/ejabberd.nix { - inherit config pkgs; - }) - - # OpenFire XMPP server - ++ optional config.services.openfire.enable - (import ../upstart-jobs/openfire.nix { - inherit config pkgs; - }) - - # JBoss service - ++ optional config.services.jboss.enable - (import ../upstart-jobs/jboss.nix { - inherit config pkgs; - }) - - # Apache Tomcat service - ++ optional config.services.tomcat.enable - (import ../upstart-jobs/tomcat.nix { - inherit config pkgs; - }) - - # Samba service. - ++ optional config.services.samba.enable - (import ../upstart-jobs/samba.nix { - inherit pkgs; - inherit (pkgs) glibc samba; - }) - - # CUPS (printing) daemon. - ++ optional config.services.printing.enable - (import ../upstart-jobs/cupsd.nix { - inherit config pkgs modprobe; - }) - - # Gateway6 - ++ optional config.services.gw6c.enable - (import ../upstart-jobs/gw6c.nix { - inherit config pkgs; - }) - - # VSFTPd server - ++ optional config.services.vsftpd.enable - (import ../upstart-jobs/vsftpd.nix { - inherit (pkgs) vsftpd; - inherit (config.services.vsftpd) anonymousUser - writeEnable anonymousUploadEnable anonymousMkdirEnable; - }) - - # X Font Server - ++ optional config.services.xfs.enable - (import ../upstart-jobs/xfs.nix { - inherit config pkgs; - }) - - ++ optional config.services.ircdHybrid.enable - (import ../upstart-jobs/ircd-hybrid.nix { - inherit config pkgs; - }) - - ++ optional config.services.bitlbee.enable - (import ../upstart-jobs/bitlbee.nix { - inherit (pkgs) bitlbee; - inherit (config.services.bitlbee) portNumber interface; - }) - - # ACPI daemon. - ++ optional config.powerManagement.enable - (import ../upstart-jobs/acpid.nix { - inherit config pkgs; - }) - - # Postfix mail server. - ++ optional config.services.postfix.enable - (import ../upstart-jobs/postfix.nix { - inherit config pkgs; - }) - - # Dovecot POP3/IMAP server. - ++ optional config.services.dovecot.enable - (import ../upstart-jobs/dovecot.nix { - inherit config pkgs; - }) - - # ISC BIND domain name server. - ++ optional config.services.bind.enable - (import ../upstart-jobs/bind.nix { - inherit config pkgs; - }) - - # Handles the reboot/halt events. - ++ (map - (event: makeJob (import ../upstart-jobs/halt.nix { - inherit (pkgs) bash utillinux; - inherit event; - })) - ["reboot" "halt" "system-halt" "power-off"] - ) - - # The terminals on ttyX. - ++ (map - (ttyNumber: makeJob (import ../upstart-jobs/mingetty.nix { - inherit (pkgs) mingetty; - inherit ttyNumber; - loginProgram = "${pkgs.pam_login}/bin/login"; - })) - (config.services.mingetty.ttys) - ) - - # Transparent TTY backgrounds. - ++ optional (config.services.ttyBackgrounds.enable && kernelPackages.splashutils != null) - (import ../upstart-jobs/tty-backgrounds.nix { - inherit (pkgs) stdenv; - inherit (kernelPackages) splashutils; - - backgrounds = - - let - - specificThemes = - config.services.ttyBackgrounds.defaultSpecificThemes - ++ config.services.ttyBackgrounds.specificThemes; - - overridenTTYs = map (x: x.tty) specificThemes; - - # Use the default theme for all the mingetty ttys and for the - # syslog tty, except those for which a specific theme is - # specified. - defaultTTYs = - pkgs.lib.filter (x: !(pkgs.lib.elem x overridenTTYs)) requiredTTYs; - - in - (map (ttyNumber: { - tty = ttyNumber; - theme = config.services.ttyBackgrounds.defaultTheme; - }) defaultTTYs) - ++ specificThemes; - - }) + jobs = map makeJob [] # User-defined events. ++ (map makeJob (config.services.extraJobs)); diff --git a/upstart-jobs/dhcpd.nix b/upstart-jobs/dhcpd.nix index d1f0a9626d5b..9604dd965b9b 100644 --- a/upstart-jobs/dhcpd.nix +++ b/upstart-jobs/dhcpd.nix @@ -1,4 +1,79 @@ -{pkgs, config}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + dhcpd = { + + enable = mkOption { + default = false; + description = " + Whether to enable the DHCP server. + "; + }; + + extraConfig = mkOption { + default = ""; + example = " + option subnet-mask 255.255.255.0; + option broadcast-address 192.168.1.255; + option routers 192.168.1.5; + option domain-name-servers 130.161.158.4, 130.161.33.17, 130.161.180.1; + option domain-name \"example.org\"; + subnet 192.168.1.0 netmask 255.255.255.0 { + range 192.168.1.100 192.168.1.200; + } + "; + description = " + Extra text to be appended to the DHCP server configuration + file. Currently, you almost certainly need to specify + something here, such as the options specifying the subnet + mask, DNS servers, etc. + "; + }; + + configFile = mkOption { + default = null; + description = " + The path of the DHCP server configuration file. If no file + is specified, a file is generated using the other options. + "; + }; + + interfaces = mkOption { + default = ["eth0"]; + description = " + The interfaces on which the DHCP server should listen. + "; + }; + + machines = mkOption { + default = []; + example = [ + { hostName = "foo"; + ethernetAddress = "00:16:76:9a:32:1d"; + ipAddress = "192.168.1.10"; + } + { hostName = "bar"; + ethernetAddress = "00:19:d1:1d:c4:9a"; + ipAddress = "192.168.1.11"; + } + ]; + description = " + A list mapping ethernet addresses to IP addresses for the + DHCP server. + "; + }; + + }; + }; + }; +in + +###### implementation let @@ -25,26 +100,34 @@ let in -{ - name = "dhcpd"; - - job = '' - description "DHCP server" - start on network-interfaces/started - stop on network-interfaces/stop +mkIf config.services.dhcpd.enable { + require = [ + options + ]; - script + services = { + extraJobs = [{ + name = "dhcpd"; + + job = '' + description "DHCP server" - mkdir -m 755 -p ${stateDir} + start on network-interfaces/started + stop on network-interfaces/stop - touch ${stateDir}/dhcpd.leases + script - exec ${pkgs.dhcp}/sbin/dhcpd -f -cf ${configFile} \ - -lf ${stateDir}/dhcpd.leases \ - ${toString cfg.interfaces} + mkdir -m 755 -p ${stateDir} - end script - ''; - + touch ${stateDir}/dhcpd.leases + + exec ${pkgs.dhcp}/sbin/dhcpd -f -cf ${configFile} \ + -lf ${stateDir}/dhcpd.leases \ + ${toString cfg.interfaces} + + end script + ''; + }]; + }; } diff --git a/upstart-jobs/dovecot.nix b/upstart-jobs/dovecot.nix index d7d74261e13a..8a70a5462d11 100644 --- a/upstart-jobs/dovecot.nix +++ b/upstart-jobs/dovecot.nix @@ -1,4 +1,45 @@ -{config, pkgs}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + dovecot = { + enable = mkOption { + default = false; + description = "Whether to enable dovecot POP3/IMAP server."; + }; + + user = mkOption { + default = "dovecot"; + description = "dovecot user name"; + }; + group = mkOption { + default = "dovecot"; + description = "dovecot group name"; + }; + + sslServerCert = mkOption { + default = ""; + description = "Server certificate"; + }; + sslCACert = mkOption { + default = ""; + description = "CA certificate used by server certificate"; + }; + sslServerKey = mkOption { + default = ""; + description = "Server key"; + }; + }; + }; + }; +in + +###### implementation + let startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; @@ -54,36 +95,51 @@ let ''; in -{ - name = "dovecot"; - users = [{ - name = cfg.user; - uid = idList.uids.dovecot; - description = "Dovecot user"; - group = cfg.group; - }]; - groups = [{ - name = cfg.group; - gid = idList.gids.dovecot; - }]; - job = '' - description "Dovecot IMAP/POP3 server" +mkIf config.services.dovecot.enable { - start on ${startingDependency}/started - stop on never + require = [ + options + ]; - start script - ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot /var/run/dovecot/login - ${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot - end script + environment = { + etc = [{ + source = pamdFile; + target = "pam.d/dovecot"; + }]; + }; - respawn ${pkgs.dovecot}/sbin/dovecot -F -c ${confFile} - ''; + users = { + extraUsers = [{ + name = cfg.user; + uid = idList.uids.dovecot; + description = "Dovecot user"; + group = cfg.group; + }]; + extraGroups = [{ + name = cfg.group; + gid = idList.gids.dovecot; + }]; + }; - extraEtc = [{ - source = pamdFile; - target = "pam.d/dovecot"; - }]; + services = { + extraJobs = [{ + name = "dovecot"; + + job = '' + description "Dovecot IMAP/POP3 server" + + start on ${startingDependency}/started + stop on never + + start script + ${pkgs.coreutils}/bin/mkdir -p /var/run/dovecot /var/run/dovecot/login + ${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot + end script + + respawn ${pkgs.dovecot}/sbin/dovecot -F -c ${confFile} + ''; + + }]; + }; } - diff --git a/upstart-jobs/ejabberd.nix b/upstart-jobs/ejabberd.nix index d2a5084068f2..390feda0e096 100644 --- a/upstart-jobs/ejabberd.nix +++ b/upstart-jobs/ejabberd.nix @@ -1,36 +1,85 @@ -args: with args; +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + ejabberd = { + enable = mkOption { + default = false; + description = "Whether to enable ejabberd server"; + }; + + spoolDir = mkOption { + default = "/var/lib/ejabberd"; + description = "Location of the spooldir of ejabberd"; + }; + + logsDir = mkOption { + default = "/var/log/ejabberd"; + description = "Location of the logfile directory of ejabberd"; + }; + + confDir = mkOption { + default = "/var/ejabberd"; + description = "Location of the config directory of ejabberd"; + }; + + virtualHosts = mkOption { + default = "\"localhost\""; + description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; + }; + }; + }; + }; +in + +###### implementation let cfg = config.services.ejabberd; in -{ - name = "ejabberd"; - - job = '' - description "EJabberd server" - start on network-interface/started - stop on network-interfaces/stop - - start script - # Initialise state data - mkdir -p ${cfg.logsDir} - - if ! test -d ${cfg.spoolDir} - then - cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib - fi - - mkdir -p ${cfg.confDir} - sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg - end script +mkIf config.services.ejabberd.enable { + + require = [ + options + ]; + + + services = { + extraJobs = [{ + name = "ejabberd"; + + job = '' + description "EJabberd server" + + start on network-interface/started + stop on network-interfaces/stop - respawn ${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin; cd ~; ejabberdctl --logs ${cfg.logsDir} --spool ${cfg.spoolDir} --config ${cfg.confDir}/ejabberd.cfg start; sleep 1d' - - stop script - ${pkgs.ejabberd}/sbin/ejabberdctl stop - end script - ''; + start script + # Initialise state data + mkdir -p ${cfg.logsDir} + + if ! test -d ${cfg.spoolDir} + then + cp -av ${pkgs.ejabberd}/var/lib/ejabberd /var/lib + fi + + mkdir -p ${cfg.confDir} + sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg + end script + + respawn ${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin; cd ~; ejabberdctl --logs ${cfg.logsDir} --spool ${cfg.spoolDir} --config ${cfg.confDir}/ejabberd.cfg start; sleep 1d' + + stop script + ${pkgs.ejabberd}/sbin/ejabberdctl stop + end script + ''; + }]; + }; } diff --git a/upstart-jobs/filesystems.nix b/upstart-jobs/filesystems.nix index 24569db11b48..10673cce5f30 100644 --- a/upstart-jobs/filesystems.nix +++ b/upstart-jobs/filesystems.nix @@ -1,120 +1,126 @@ -{utillinux, e2fsprogs, fileSystems, mount}: +{pkgs, config, ...}: + +###### implementation let - - # !!! use XML + inherit (pkgs) e2fsprogs; mountPoints = map (fs: fs.mountPoint) fileSystems; + fileSystems = config.fileSystems; devices = map (fs: if fs ? device then fs.device else "LABEL=" + fs.label) fileSystems; fsTypes = map (fs: if fs ? fsType then fs.fsType else "auto") fileSystems; optionss = map (fs: if fs ? options then fs.options else "defaults") fileSystems; autocreates = map (fs: if fs ? autocreate then fs.autocreate else "0") fileSystems; + mount = config.system.sbin.mount; -in - -{ - name = "filesystems"; + job = '' + start on startup + start on new-devices + start on ip-up - job = " -start on startup -start on new-devices -start on ip-up - -script + script PATH=${e2fsprogs}/sbin:$PATH - + mountPoints=(${toString mountPoints}) devices=(${toString devices}) fsTypes=(${toString fsTypes}) optionss=(${toString optionss}) autocreates=(${toString autocreates}) - + newDevices=1 - + # If we mount any file system, we repeat this loop, because new # mount opportunities may have become available (such as images # for loopback mounts). - - while test -n \"$newDevices\"; do - - newDevices= - - for ((n = 0; n < \${#mountPoints[*]}; n++)); do - mountPoint=\${mountPoints[$n]} - device=\${devices[$n]} - fsType=\${fsTypes[$n]} - options=\${optionss[$n]} - autocreate=\${autocreates[$n]} - - isLabel= - if echo \"$device\" | grep -q '^LABEL='; then isLabel=1; fi - - isPseudo= - if test \"$fsType\" = \"nfs\" || test \"$fsType\" = \"tmpfs\" || - test \"$fsType\" = \"ext3cow\"; then isPseudo=1; fi - - if ! test -n \"$isLabel\" -o -n \"$isPseudo\" -o -e \"$device\"; then - echo \"skipping $device, doesn't exist (yet)\" - continue - fi - - # !!! quick hack: if mount point already exists, try a - # remount to change the options but nothing else. - if cat /proc/mounts | grep -F -q \" $mountPoint \"; then - echo \"remounting $device on $mountPoint\" - ${mount}/bin/mount -t \"$fsType\" \\ - -o remount,\"$options\" \\ - \"$device\" \"$mountPoint\" || true - continue - fi - - # If $device is already mounted somewhere else, unmount it first. - # !!! Note: we use /etc/mtab, not /proc/mounts, because mtab - # contains more accurate info when using loop devices. - - # !!! not very smart about labels yet; should resolve the label somehow. - if test -z \"$isLabel\" -a -z \"$isPseudo\"; then - - device=$(readlink -f \"$device\") - - prevMountPoint=$( - cat /etc/mtab \\ - | grep \"^$device \" \\ - | sed 's|^[^ ]\\+ \\+\\([^ ]\\+\\).*|\\1|' \\ - ) - - if test \"$prevMountPoint\" = \"$mountPoint\"; then - echo \"remounting $device on $mountPoint\" - ${mount}/bin/mount -t \"$fsType\" \\ - -o remount,\"$options\" \\ - \"$device\" \"$mountPoint\" || true - continue - fi - - if test -n \"$prevMountPoint\"; then - echo \"unmount $device from $prevMountPoint\" - ${mount}/bin/umount \"$prevMountPoint\" || true - fi - - fi - - echo \"mounting $device on $mountPoint\" - - # !!! should do something with the result; also prevent repeated fscks. - if test -z \"$isPseudo\"; then - fsck -a \"$device\" || true - fi - - if test \"\$autocreate\" = 1; then mkdir -p \"\$mountPoint\"; fi - - if ${mount}/bin/mount -t \"$fsType\" -o \"$options\" \"$device\" \"$mountPoint\"; then - newDevices=1 - fi - - done - + + while test -n "$newDevices"; do + + newDevices= + + for ((n = 0; n < ''${#mountPoints[*]}; n++)); do + mountPoint=''${mountPoints[$n]} + device=''${devices[$n]} + fsType=''${fsTypes[$n]} + options=''${optionss[$n]} + autocreate=''${autocreates[$n]} + + isLabel= + if echo "$device" | grep -q '^LABEL='; then isLabel=1; fi + + isPseudo= + if test "$fsType" = "nfs" || test "$fsType" = "tmpfs" || + test "$fsType" = "ext3cow"; then isPseudo=1; fi + + if ! test -n "$isLabel" -o -n "$isPseudo" -o -e "$device"; then + echo "skipping $device, doesn't exist (yet)" + continue + fi + + # !!! quick hack: if mount point already exists, try a + # remount to change the options but nothing else. + if cat /proc/mounts | grep -F -q " $mountPoint "; then + echo "remounting $device on $mountPoint" + ${mount}/bin/mount -t "$fsType" \ + -o remount,"$options" \ + "$device" "$mountPoint" || true + continue + fi + + # If $device is already mounted somewhere else, unmount it first. + # !!! Note: we use /etc/mtab, not /proc/mounts, because mtab + # contains more accurate info when using loop devices. + + # !!! not very smart about labels yet; should resolve the label somehow. + if test -z "$isLabel" -a -z "$isPseudo"; then + + device=$(readlink -f "$device") + + prevMountPoint=$( + cat /etc/mtab \ + | grep "^$device " \ + | sed 's|^[^ ]\+ \+\([^ ]\+\).*|\1|' \ + ) + + if test "$prevMountPoint" = "$mountPoint"; then + echo "remounting $device on $mountPoint" + ${mount}/bin/mount -t "$fsType" \ + -o remount,"$options" \ + "$device" "$mountPoint" || true + continue + fi + + if test -n "$prevMountPoint"; then + echo "unmount $device from $prevMountPoint" + ${mount}/bin/umount "$prevMountPoint" || true + fi + + fi + + echo "mounting $device on $mountPoint" + + # !!! should do something with the result; also prevent repeated fscks. + if test -z "$isPseudo"; then + fsck -a "$device" || true + fi + + if test "$autocreate" = 1; then mkdir -p "$mountPoint"; fi + + if ${mount}/bin/mount -t "$fsType" -o "$options" "$device" "$mountPoint"; then + newDevices=1 + fi + + done + done + + end script + ''; +in -end script - "; - +{ + services = { + extraJobs = [{ + name = "filesystems"; + inherit job; + }]; + }; } diff --git a/upstart-jobs/gnunet.nix b/upstart-jobs/gnunet.nix index 3b3de2d97b3d..5fe7579d8fed 100644 --- a/upstart-jobs/gnunet.nix +++ b/upstart-jobs/gnunet.nix @@ -1,64 +1,218 @@ -{ gnunet, gnunetConfig, lib, writeText }: +{pkgs, config, ...}: -assert gnunetConfig.enable; +###### interface +let + inherit (pkgs.lib) mkOption mkIf; -{ - name = "gnunetd"; + options = { + services = { + gnunet = { + + enable = mkOption { + default = false; + description = '' + Whether to run the GNUnet daemon. GNUnet is GNU's anonymous + peer-to-peer communication and file sharing framework. + ''; + }; - users = [ - { name = "gnunetd"; - uid = (import ../system/ids.nix).uids.gnunetd; - description = "GNUnet Daemon User"; - home = "/var/empty"; - } + home = mkOption { + default = "/var/lib/gnunet"; + description = '' + Directory where the GNUnet daemon will store its data. + ''; + }; + + debug = mkOption { + default = false; + description = '' + When true, run in debug mode; gnunetd will not daemonize and + error messages will be written to stderr instead of a + logfile. + ''; + }; + + logLevel = mkOption { + default = "ERROR"; + example = "INFO"; + description = '' + Log level of the deamon (see `gnunetd(1)' for details). + ''; + }; + + hostLists = mkOption { + default = [ + "http://gnunet.org/hostlist.php" + "http://gnunet.mine.nu:8081/hostlist" + "http://vserver1236.vserver-on.de/hostlist-074" + ]; + description = '' + URLs of host lists. + ''; + }; + + + applications = mkOption { + default = [ "advertising" "getoption" "fs" "stats" "traffic" ]; + example = [ "chat" "fs" ]; + description = '' + List of GNUnet applications supported by the daemon. Note that + `fs', which means "file sharing", is probably the one you want. + ''; + }; + + transports = mkOption { + default = [ "udp" "tcp" "http" "nat" ]; + example = [ "smtp" "http" ]; + description = '' + List of transport methods used by the server. + ''; + }; + + fileSharing = { + quota = mkOption { + default = 1024; + description = '' + Maximum file system usage (in MiB) for file sharing. + ''; + }; + + activeMigration = mkOption { + default = false; + description = '' + Whether to allow active migration of content originating + from other nodes. + ''; + }; + }; + + load = { + maxNetDownBandwidth = mkOption { + default = 50000; + description = '' + Maximum bandwidth usage (in bits per second) for GNUnet + when downloading data. + ''; + }; + + maxNetUpBandwidth = mkOption { + default = 50000; + description = '' + Maximum bandwidth usage (in bits per second) for GNUnet + when downloading data. + ''; + }; + + hardNetUpBandwidth = mkOption { + default = 0; + description = '' + Hard bandwidth limit (in bits per second) when uploading + data. + ''; + }; + + maxCPULoad = mkOption { + default = 100; + description = '' + Maximum CPU load (percentage) authorized for the GNUnet + daemon. + ''; + }; + + interfaces = mkOption { + default = [ "eth0" ]; + example = [ "wlan0" "eth1" ]; + description = '' + List of network interfaces to use. + ''; + }; + }; + + extraOptions = mkOption { + default = ""; + example = '' + [NETWORK] + INTERFACE = eth3 + ''; + description = '' + Additional options that will be copied verbatim in `gnunetd.conf'. + See `gnunetd.conf(5)' for details. + ''; + }; + }; + }; + }; +in + +###### implementation + +mkIf config.services.gnunet.enable { + require = [ + options ]; - job = - with gnunetConfig; - let configFile = writeText "gnunetd.conf" '' - [PATHS] - GNUNETD_HOME = ${home} + users = { + extraUsers = [ + { name = "gnunetd"; + uid = (import ../system/ids.nix).uids.gnunetd; + description = "GNUnet Daemon User"; + home = "/var/empty"; + } + ]; + }; - [GNUNETD] - HOSTLISTURL = ${lib.concatStringsSep " " hostLists} - APPLICATIONS = ${lib.concatStringsSep " " applications} - TRANSPORTS = ${lib.concatStringsSep " " transports} + services = { + extraJobs = [{ + name = "gnunetd"; - [LOAD] - MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth} - MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth} - HARDUPLIMIT = ${toString load.hardNetUpBandwidth} - MAXCPULOAD = ${toString load.maxCPULoad} - INTERFACES = ${lib.concatStringsSep " " load.interfaces} + job = + with config.services.gnunet; + let + inherit (pkgs) lib gnunet; + configFile = pkgs.writeText "gnunetd.conf" '' + [PATHS] + GNUNETD_HOME = ${home} - [FS] - QUOTA = ${toString fileSharing.quota} - ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"} + [GNUNETD] + HOSTLISTURL = ${lib.concatStringsSep " " hostLists} + APPLICATIONS = ${lib.concatStringsSep " " applications} + TRANSPORTS = ${lib.concatStringsSep " " transports} - [MODULES] - sqstore = sqstore_sqlite - dstore = dstore_sqlite - topology = topology_default + [LOAD] + MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth} + MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth} + HARDUPLIMIT = ${toString load.hardNetUpBandwidth} + MAXCPULOAD = ${toString load.maxCPULoad} + INTERFACES = ${lib.concatStringsSep " " load.interfaces} - ${extraOptions} - ''; + [FS] + QUOTA = ${toString fileSharing.quota} + ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"} - in '' -description "The GNUnet Daemon" + [MODULES] + sqstore = sqstore_sqlite + dstore = dstore_sqlite + topology = topology_default -start on network-interfaces/started -stop on network-interfaces/stop + ${extraOptions} + ''; + in '' + description "The GNUnet Daemon" -start script - test -d "${home}" || \ - ( mkdir -m 755 -p "${home}" && chown -R gnunetd:users "${home}") -end script + start on network-interfaces/started + stop on network-interfaces/stop -respawn ${gnunet}/bin/gnunetd \ - ${if debug then "--debug" else "" } \ - --user="gnunetd" \ - --config="${configFile}" \ - --log="${logLevel}" -''; + start script + test -d "${home}" || \ + ( mkdir -m 755 -p "${home}" && chown -R gnunetd:users "${home}") + end script + respawn ${gnunet}/bin/gnunetd \ + ${if debug then "--debug" else "" } \ + --user="gnunetd" \ + --config="${configFile}" \ + --log="${logLevel}" + ''; + }]; + }; } diff --git a/upstart-jobs/gw6c.nix b/upstart-jobs/gw6c.nix index f3332f9e8f3d..21596c22dfad 100644 --- a/upstart-jobs/gw6c.nix +++ b/upstart-jobs/gw6c.nix @@ -1,8 +1,106 @@ -{config, pkgs}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + gw6c = { + enable = mkOption { + default = false; + description = " + Whether to enable Gateway6 client (IPv6 tunnel). + "; + }; + + autorun = mkOption { + default = true; + description = " + Switch to false to create upstart-job and configuration, + but not run it automatically + "; + }; + + username = mkOption { + default = ""; + description = " + Your Gateway6 login name, if any. + "; + }; + + password = mkOption { + default = ""; + description = " + Your Gateway6 password, if any. + "; + }; + + server = mkOption { + default = "anon.freenet6.net"; + example = "broker.freenet6.net"; + description = " + Used Gateway6 server. + "; + }; + + keepAlive = mkOption { + default = "30"; + example = "2"; + description = " + Gateway6 keep-alive period. + "; + }; + + everPing = mkOption { + default = "1000000"; + example = "2"; + description = " + Gateway6 manual ping period. + "; + }; + + waitPingableBroker = mkOption { + default = true; + example = false; + description = " + Whether to wait until tunnel broker returns ICMP echo. + "; + }; + }; + }; + security = { + seccureKeys = { + public = mkOption { + default = /var/elliptic-keys/public; + description = " + Public key. Make it path argument, so it is copied into store and + hashed. + + The key is used to encrypt Gateway 6 configuration in store, as it + contains a password for external service. Unfortunately, + derivation file should be protected by other means. For example, + nix-http-export.cgi will happily export any non-derivation path, + but not a derivation. + "; + }; + private = mkOption { + default = "/var/elliptic-keys/private"; + description = " + Private key. Make it string argument, so it is not copied into store. + "; + }; + }; + }; + }; +in + +###### implementation + let cfg = config.services.gw6c; procps = pkgs.procps; - gw6cService = import ../services/gw6c { + gw6cService = import ../../services/gw6c { inherit (pkgs) stdenv gw6c coreutils procps upstart iputils gnused gnugrep seccureUser writeScript; @@ -17,16 +115,26 @@ let waitPingableBroker = cfg.waitPingableBroker; }; in -{ + + +mkIf config.services.gw6c.enable { + require = [ + options + ]; + + services = { + extraJobs = [{ name = "gw6c"; users = []; groups = []; - job = " -description \"Gateway6 client\" + job = '' + description \"Gateway6 client\" -start on ${ if cfg.autorun then "network-interfaces/started" else "never" } -stop on network-interfaces/stop + start on ${ if cfg.autorun then "network-interfaces/started" else "never" } + stop on network-interfaces/stop -respawn ${gw6cService}/bin/control start -"; + respawn ${gw6cService}/bin/control start + ''; + }]; + }; } diff --git a/upstart-jobs/halt.nix b/upstart-jobs/halt.nix index 9e6c798ea868..d98a3b5eea47 100644 --- a/upstart-jobs/halt.nix +++ b/upstart-jobs/halt.nix @@ -1,103 +1,120 @@ -{bash, event, utillinux}: +{pkgs, config, ...}: +###### implementation + + +/* FIXME assert event == "reboot" || event == "halt" || event == "system-halt" || event == "power-off"; +*/ + +let + + inherit (pkgs) bash utillinux; + + jobFun = event : { + name = "sys-" + event; + + job = '' + start on ${event} + + script + set +e # continue in case of errors + + exec < /dev/tty1 > /dev/tty1 2>&1 + echo "" + echo "<<< SYSTEM SHUTDOWN >>>" + echo "" + + export PATH=${utillinux}/bin:${utillinux}/sbin:$PATH + + + # Set the hardware clock to the system time. + echo "Setting the hardware clock..." + hwclock --systohc --utc || true + + + # Do an initial sync just in case. + sync || true + + + # Kill all remaining processes except init and this one. + echo "Sending the TERM signal to all processes..." + kill -TERM -1 || true + + sleep 1 # wait briefly + + echo "Sending the KILL signal to all processes..." + kill -KILL -1 || true + + + # Unmount helper functions. + getMountPoints() { + cat /proc/mounts \ + | grep -v '^rootfs' \ + | sed 's|^[^ ]\+ \+\([^ ]\+\).*|\1|' \ + | grep -v '/proc\|/sys\|/dev' + } + + getDevice() { + local mountPoint=$1 + cat /proc/mounts \ + | grep -v '^rootfs' \ + | grep "^[^ ]\+ \+$mountPoint \+" \ + | sed 's|^\([^ ]\+\).*|\1|' + } + + # Unmount file systems. We repeat this until no more file systems + # can be unmounted. This is to handle loopback devices, file + # systems mounted on other file systems and so on. + tryAgain=1 + while test -n "$tryAgain"; do + tryAgain= + + for mp in $(getMountPoints); do + device=$(getDevice $mp) + echo "unmounting $mp..." + if umount -f -n "$mp"; then + if test "$mp" != /; then tryAgain=1; fi + else + mount -n -o remount,ro "$mp" || true + fi + + # Hack: work around a bug in mount (mount -o remount on a + # loop device forgets the loop=/dev/loopN entry in + # /etc/mtab). + if echo "$device" | grep -q '/dev/loop'; then + echo "removing loop device $device..." + losetup -d "$device" || true + fi + done + done + + cat /proc/mounts + + + # Final sync. + sync || true + + + # Right now all events above power off the system. + if test ${event} = reboot; then + exec reboot -f + else + exec halt -f -p + fi + + end script + ''; + }; + +in + { - name = "sys-" + event; - - job = " -start on ${event} - -script - set +e # continue in case of errors - - exec < /dev/tty1 > /dev/tty1 2>&1 - echo \"\" - echo \"<<< SYSTEM SHUTDOWN >>>\" - echo \"\" - - export PATH=${utillinux}/bin:${utillinux}/sbin:$PATH - - - # Set the hardware clock to the system time. - echo \"Setting the hardware clock...\" - hwclock --systohc --utc || true - - - # Do an initial sync just in case. - sync || true - - - # Kill all remaining processes except init and this one. - echo \"Sending the TERM signal to all processes...\" - kill -TERM -1 || true - - sleep 1 # wait briefly - - echo \"Sending the KILL signal to all processes...\" - kill -KILL -1 || true - - - # Unmount helper functions. - getMountPoints() { - cat /proc/mounts \\ - | grep -v '^rootfs' \\ - | sed 's|^[^ ]\\+ \\+\\([^ ]\\+\\).*|\\1|' \\ - | grep -v '/proc\\|/sys\\|/dev' - } - - getDevice() { - local mountPoint=$1 - cat /proc/mounts \\ - | grep -v '^rootfs' \\ - | grep \"^[^ ]\\+ \\+$mountPoint \\+\" \\ - | sed 's|^\\([^ ]\\+\\).*|\\1|' - } - - # Unmount file systems. We repeat this until no more file systems - # can be unmounted. This is to handle loopback devices, file - # systems mounted on other file systems and so on. - tryAgain=1 - while test -n \"$tryAgain\"; do - tryAgain= - - for mp in $(getMountPoints); do - device=$(getDevice $mp) - echo \"unmounting $mp...\" - if umount -f -n \"$mp\"; then - if test \"$mp\" != /; then tryAgain=1; fi - else - mount -n -o remount,ro \"$mp\" || true - fi - - # Hack: work around a bug in mount (mount -o remount on a - # loop device forgets the loop=/dev/loopN entry in - # /etc/mtab). - if echo \"$device\" | grep -q '/dev/loop'; then - echo \"removing loop device $device...\" - losetup -d \"$device\" || true - fi - done - done - - cat /proc/mounts - - - # Final sync. - sync || true - - - # Right now all events above power off the system. - if test ${event} = reboot; then - exec reboot -f - else - exec halt -f -p - fi - -end script - "; - + services = { + extraJobs = map jobFun ["reboot" "halt" "system-halt" "power-off"]; + }; } diff --git a/upstart-jobs/httpd.nix b/upstart-jobs/httpd.nix index f9613f931ffa..1dd25afbf9cd 100644 --- a/upstart-jobs/httpd.nix +++ b/upstart-jobs/httpd.nix @@ -1,4 +1,14 @@ -{config, pkgs, glibc, extraConfig}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + # options have been moved to the apache-httpd/default.nix file + +in + +###### implementation let @@ -21,6 +31,11 @@ let applicationMappings = cfg.mod_jk.applicationMappings; startingDependency = if config.services.gw6c.enable && config.services.gw6c.autorun then "gw6c" else "network-interfaces"; + + + extraConfig = pkgs.lib.concatStringsSep "\n" + (pkgs.lib.catAttrs "extraHttpdConfig" config.services.extraJobs); + webServer = import ../../services/apache-httpd { inherit (pkgs) apacheHttpd coreutils; @@ -32,6 +47,7 @@ let user group adminAddr logDir stateDir applicationMappings; noUserDir = !cfg.enableUserDir; + extraDirectories = extraConfig + "\n" + cfg.extraConfig; subServices = @@ -72,41 +88,47 @@ let ) ) ) - ) - /* ++ - - (optional cfg.extraSubservices.enable - (map (service : service webServer pkgs) cfg.extraSubservices.services) - ) */; + ); }; in -{ - name = "httpd"; - - users = [ - { name = user; - description = "Apache httpd user"; - } +mkIf (config.services.httpd.enable && !config.services.httpd.experimental) { + + require = [ + # options have been moved to the apache-httpd/default.nix file ]; - groups = [ - { name = group; - } - ]; - - job = " -description \"Apache HTTPD\" - -start on ${startingDependency}/started -stop on ${startingDependency}/stop - -start script - ${webServer}/bin/control prepare -end script - -respawn ${webServer}/bin/control run - "; + users = { + extraUsers = [ + { name = user; + description = "Apache httpd user"; + } + ]; + + extraGroups = [ + { name = group; + } + ]; + }; + + services = { + extraJobs = [{ + name = "httpd"; + + job = '' + description \"Apache HTTPD\" + + start on ${startingDependency}/started + stop on ${startingDependency}/stop + + start script + ${webServer}/bin/control prepare + end script + + respawn ${webServer}/bin/control run + ''; + }]; + }; } diff --git a/upstart-jobs/ifplugd.nix b/upstart-jobs/ifplugd.nix index 4536ee8b41e5..c1b9c4e56204 100644 --- a/upstart-jobs/ifplugd.nix +++ b/upstart-jobs/ifplugd.nix @@ -1,7 +1,42 @@ -{ifplugd, config, writeScript, bash}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + networking = { + interfaceMonitor = { + + enable = mkOption { + default = false; + description = " + If true, monitor Ethernet interfaces for + cables being plugged in or unplugged. When this occurs, the + dhclient service is restarted to + automatically obtain a new IP address. This is useful for + roaming users (laptops). + "; + }; + + beep = mkOption { + default = false; + description = " + If true, beep when an Ethernet cable is + plugged in or unplugged. + "; + }; + }; + }; + }; +in + +###### implementation let + inherit (pkgs) ifplugd writeScript bash; + # The ifplugd action script, which is called whenever the link # status changes (i.e., a cable is plugged in or unplugged). We do # nothing when a cable is unplugged. When a cable is plugged in, we @@ -17,19 +52,27 @@ let in -{ - name = "ifplugd"; +mkIf config.networking.interfaceMonitor.enable { + require = [ + options + ]; - extraPath = [ifplugd]; - - job = " -description \"Network interface connectivity monitor\" + services = { + extraJobs = [{ + name = "ifplugd"; -start on network-interfaces/started -stop on network-interfaces/stop + extraPath = [ifplugd]; + + job = '' + description "Network interface connectivity monitor" -respawn ${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \\ - ${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \\ - --run ${plugScript}"; - + start on network-interfaces/started + stop on network-interfaces/stop + + respawn ${ifplugd}/sbin/ifplugd --no-daemon --no-startup --no-shutdown \ + ${if config.networking.interfaceMonitor.beep then "" else "--no-beep"} \ + --run ${plugScript} + ''; + }]; + }; } diff --git a/upstart-jobs/ircd-hybrid.nix b/upstart-jobs/ircd-hybrid.nix index 4183673cef8d..b78c65e96b9b 100644 --- a/upstart-jobs/ircd-hybrid.nix +++ b/upstart-jobs/ircd-hybrid.nix @@ -1,38 +1,130 @@ -{config, pkgs}: +{pkgs, config, ...}: + +###### interface let - cfg = config.services.ircdHybrid; - ircdService = import ../services/ircd-hybrid { - stdenv = pkgs.stdenv; - inherit (pkgs) ircdHybrid coreutils - su iproute gnugrep procps; - serverName = cfg.serverName; - sid = cfg.sid; - description = cfg.description; - rsaKey = cfg.rsaKey; - certificate = cfg.certificate; - adminEmail = cfg.adminEmail; - extraIPs = cfg.extraIPs; - extraPort = cfg.extraPort; - gw6cEnabled = (config.services.gw6c.enable) && - (config.services.gw6c.autorun); + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + ircdHybrid = { + + enable = mkOption { + default = false; + description = " + Enable IRCD. + "; }; + serverName = mkOption { + default = "hades.arpa"; + description = " + IRCD server name. + "; + }; + + sid = mkOption { + default = "0NL"; + description = " + IRCD server unique ID in a net of servers. + "; + }; + + description = mkOption { + default = "Hybrid-7 IRC server."; + description = " + IRCD server description. + "; + }; + + rsaKey = mkOption { + default = null; + example = /root/certificates/irc.key; + description = " + IRCD server RSA key. + "; + }; + + certificate = mkOption { + default = null; + example = /root/certificates/irc.pem; + description = " + IRCD server SSL certificate. There are some limitations - read manual. + "; + }; + + adminEmail = mkOption { + default = ""; + example = ""; + description = " + IRCD server administrator e-mail. + "; + }; + + extraIPs = mkOption { + default = []; + example = ["127.0.0.1"]; + description = " + Extra IP's to bind. + "; + }; + + extraPort = mkOption { + default = "7117"; + description = " + Extra port to avoid filtering. + "; + }; + + }; + }; + }; +in + +###### implementation + +let + cfg = config.services.ircdHybrid; + ircdService = import ../../services/ircd-hybrid { + stdenv = pkgs.stdenv; + inherit (pkgs) ircdHybrid coreutils + su iproute gnugrep procps; + serverName = cfg.serverName; + sid = cfg.sid; + description = cfg.description; + rsaKey = cfg.rsaKey; + certificate = cfg.certificate; + adminEmail = cfg.adminEmail; + extraIPs = cfg.extraIPs; + extraPort = cfg.extraPort; + gw6cEnabled = (config.services.gw6c.enable) && + (config.services.gw6c.autorun); + }; + startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; in -{ - name = "ircd-hybrid"; - users = [ { - name = "ircd"; - description = "IRCD owner."; - } ]; - groups = [{name = "ircd";}]; - job = " -description = \"IRCD Hybrid server.\" -start on ${startingDependency}/started -stop on ${startingDependency}/stop +mkIf config.services.ircdHybrid.enable { + require = [ + options + ]; -respawn ${ircdService}/bin/control start -"; + services = { + extraJobs = [{ + name = "ircd-hybrid"; + users = [ { + name = "ircd"; + description = "IRCD owner."; + } ]; + groups = [{name = "ircd";}]; + job = '' + description = "IRCD Hybrid server." + + start on ${startingDependency}/started + stop on ${startingDependency}/stop + + respawn ${ircdService}/bin/control start + ''; + }]; + }; } diff --git a/upstart-jobs/jboss.nix b/upstart-jobs/jboss.nix index 6c35fe064366..322ed92b920d 100644 --- a/upstart-jobs/jboss.nix +++ b/upstart-jobs/jboss.nix @@ -1,21 +1,82 @@ -args: with args; +{pkgs, config, ...}: +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + jboss = { + enable = mkOption { + default = false; + description = "Whether to enable jboss"; + }; + + tempDir = mkOption { + default = "/tmp"; + description = "Location where JBoss stores its temp files"; + }; + + logDir = mkOption { + default = "/var/log/jboss"; + description = "Location of the logfile directory of JBoss"; + }; + + serverDir = mkOption { + description = "Location of the server instance files"; + default = "/var/jboss/server"; + }; + + deployDir = mkOption { + description = "Location of the deployment files"; + default = "/nix/var/nix/profiles/default/server/default/deploy/"; + }; + + libUrl = mkOption { + default = "file:///nix/var/nix/profiles/default/server/default/lib"; + description = "Location where the shared library JARs are stored"; + }; + + user = mkOption { + default = "nobody"; + description = "User account under which jboss runs."; + }; + + useJK = mkOption { + default = false; + description = "Whether to use to connector to the Apache HTTP server"; + }; + }; + }; + }; +in + +###### implementation let cfg = config.services.jboss; -jbossService = import ../services/jboss { +jbossService = import ../../services/jboss { inherit (pkgs) stdenv jboss su; inherit (cfg) tempDir logDir libUrl deployDir serverDir user useJK; }; in -{ - name = "jboss"; - job = " -description \"JBoss server\" -stop on shutdown +mkIf config.services.jboss.enable { + require = [ + options + ]; -respawn ${jbossService}/bin/control start - "; + services = { + extraJobs = [{ + name = "jboss"; + job = '' + description \"JBoss server\" + + stop on shutdown + + respawn ${jbossService}/bin/control start + ''; + }]; + }; } diff --git a/upstart-jobs/kbd.nix b/upstart-jobs/kbd.nix index 8be001b03d60..504b902bcb13 100644 --- a/upstart-jobs/kbd.nix +++ b/upstart-jobs/kbd.nix @@ -1,78 +1,109 @@ -{glibc, kbd, gzip, ttyNumbers, defaultLocale, consoleFont, consoleKeyMap}: +{pkgs, config, ...}: let + inherit (pkgs.lib) mkOption; + # think about where to put this chunk of code! + # required by other pieces as well + requiredTTYs = config.services.mingetty.ttys + ++ config.boot.extraTTYs + ++ [config.services.syslogd.tty]; + ttyNumbers = requiredTTYs; ttys = map (nr: "/dev/tty" + toString nr) ttyNumbers; + defaultLocale = config.i18n.defaultLocale; + consoleFont = config.i18n.consoleFont; + consoleKeyMap = config.i18n.consoleKeyMap; in +###### implementation + +# most options are defined in i18n.nix + { - name = "kbd"; - extraPath = [ - kbd + inherit requiredTTYs; # pass them to upstart-job/default.nix + + # dummy option so that requiredTTYs can be passed, see above (FIXME) + require = [ + { + requiredTTYs = mkOption { + default = []; + }; + } ]; - - job = " - description \"Keyboard / console initialisation\" - start on udev - - script - - export LANG=${defaultLocale} - export PATH=${gzip}/bin:$PATH # Needed by setfont - - set +e # continue in case of errors + services = { + extraJobs = [{ + name = "kbd"; + extraPath = [ + pkgs.kbd + ]; - # Enable or disable UTF-8 mode. This is based on - # unicode_{start,stop}. - echo 'Enabling or disabling Unicode mode...' + job = " + description \"Keyboard / console initialisation\" - charMap=$(${glibc}/bin/locale charmap) + start on udev - if test \"$charMap\" = UTF-8; then + script - for tty in ${toString ttys}; do + export LANG=${defaultLocale} + export PATH=${pkgs.gzip}/bin:$PATH # Needed by setfont - # Tell the console output driver that the bytes arriving are - # UTF-8 encoded multibyte sequences. - echo -n -e '\\033%G' > $tty + set +e # continue in case of errors - done + + # Enable or disable UTF-8 mode. This is based on + # unicode_{start,stop}. + echo 'Enabling or disabling Unicode mode...' - # Set the keyboard driver in UTF-8 mode. - ${kbd}/bin/kbd_mode -u + charMap=$(${pkgs.glibc}/bin/locale charmap) - else + if test \"$charMap\" = UTF-8; then - for tty in ${toString ttys}; do + for tty in ${toString ttys}; do - # Tell the console output driver that the bytes arriving are - # UTF-8 encoded multibyte sequences. - echo -n -e '\\033%@' > $tty + # Tell the console output driver that the bytes arriving are + # UTF-8 encoded multibyte sequences. + echo -n -e '\\033%G' > $tty - done + done - # Set the keyboard driver in ASCII (or any 8-bit character - # set) mode. - ${kbd}/bin/kbd_mode -a + # Set the keyboard driver in UTF-8 mode. + ${pkgs.kbd}/bin/kbd_mode -u - fi + else + + for tty in ${toString ttys}; do + + # Tell the console output driver that the bytes arriving are + # UTF-8 encoded multibyte sequences. + echo -n -e '\\033%@' > $tty + + done + + # Set the keyboard driver in ASCII (or any 8-bit character + # set) mode. + ${pkgs.kbd}/bin/kbd_mode -a + + fi - # Set the console font. - for tty in ${toString ttys}; do - ${kbd}/bin/setfont -C $tty ${consoleFont} - done + # Set the console font. + for tty in ${toString ttys}; do + ${pkgs.kbd}/bin/setfont -C $tty ${consoleFont} + done - # Set the keymap. - ${kbd}/bin/loadkeys '${consoleKeyMap}' + # Set the keymap. + ${pkgs.kbd}/bin/loadkeys '${consoleKeyMap}' - end script - "; - + end script + "; + + }]; + }; + } diff --git a/upstart-jobs/klogd.nix b/upstart-jobs/klogd.nix index 35207b339bda..59ab51fea928 100644 --- a/upstart-jobs/klogd.nix +++ b/upstart-jobs/klogd.nix @@ -1,26 +1,33 @@ -{sysklogd, writeText, config}: +{pkgs, config, ...}: +###### implementation let + inherit (pkgs.lib); - klogdCmd = "${sysklogd}/sbin/klogd -c 1 -2 -k $(dirname $(readlink -f /var/run/booted-system/kernel))/System.map"; + klogdCmd = "${pkgs.sysklogd}/sbin/klogd -c 1 -2 -k $(dirname $(readlink -f /var/run/booted-system/kernel))/System.map"; in { - name = "klogd"; - - job = '' - description "Kernel log daemon" - - start on syslogd - stop on shutdown - start script - # !!! this hangs for some reason (it blocks reading from - # /proc/kmsg). - #${klogdCmd} -o - end script + services = { + extraJobs = [{ + name = "klogd"; + + job = '' + description "Kernel log daemon" + + start on syslogd + stop on shutdown - respawn ${klogdCmd} -n - ''; + start script + # !!! this hangs for some reason (it blocks reading from + # /proc/kmsg). + #${klogdCmd} -o + end script + + respawn ${klogdCmd} -n + ''; + }]; + }; } diff --git a/upstart-jobs/ldap/default.nix b/upstart-jobs/ldap/default.nix new file mode 100644 index 000000000000..4c964cd79f29 --- /dev/null +++ b/upstart-jobs/ldap/default.nix @@ -0,0 +1,76 @@ +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + users = { + ldap = { + + enable = mkOption { + default = false; + description = " + Whether to enable authentication against an LDAP server. + "; + }; + + server = mkOption { + example = "ldap://ldap.example.org/"; + description = " + The URL of the LDAP server. + "; + }; + + base = mkOption { + example = "dc=example,dc=org"; + description = " + The distinguished name of the search base. + "; + }; + + useTLS = mkOption { + default = false; + description = " + If enabled, use TLS (encryption) over an LDAP (port 389) + connection. The alternative is to specify an LDAPS server (port + 636) in or to forego + security. + "; + }; + + }; + }; + }; +in + +###### implementation + +mkIf config.users.ldap.enable { + require = [ + options + ]; + + # LDAP configuration. + environment = { + etc = [ + + # Careful: OpenLDAP seems to be very picky about the indentation of + # this file. Directives HAVE to start in the first column! + { source = pkgs.writeText "ldap.conf" '' + uri ${config.users.ldap.server} + base ${config.users.ldap.base} + + ${ + if config.users.ldap.useTLS then '' + ssl start_tls + tls_checkpeer no + '' else "" + } + ''; + target = "ldap.conf"; + } + ]; + }; + +} diff --git a/etc/ldap.conf.nix b/upstart-jobs/ldap/ldap.conf.nix similarity index 100% rename from etc/ldap.conf.nix rename to upstart-jobs/ldap/ldap.conf.nix diff --git a/upstart-jobs/lshd.nix b/upstart-jobs/lshd.nix index 0a13d9ba7ee7..9db99bce493f 100644 --- a/upstart-jobs/lshd.nix +++ b/upstart-jobs/lshd.nix @@ -1,54 +1,175 @@ -{lsh, xauth, lib, nssModulesPath, lshdConfig}: +{pkgs, config, ...}: -with builtins; -with lib; +###### interface +let + inherit (pkgs.lib) mkOption mkIf; -{ - name = "lshd"; - - job = with lshdConfig; '' -description "GNU lshd SSH2 daemon" + options = { + services = { + lshd = { -start on network-interfaces/started -stop on network-interfaces/stop + enable = mkOption { + default = false; + description = '' + Whether to enable the GNU lshd SSH2 daemon, which allows + secure remote login. + ''; + }; -env LD_LIBRARY_PATH=${nssModulesPath} + portNumber = mkOption { + default = 22; + description = '' + The port on which to listen for connections. + ''; + }; -start script - test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh - test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh + interfaces = mkOption { + default = []; + description = '' + List of network interfaces where listening for connections. + When providing the empty list, `[]', lshd listens on all + network interfaces. + ''; + example = [ "localhost" "1.2.3.4:443" ]; + }; - if ! test -f /var/spool/lsh/yarrow-seed-file - then - ${lsh}/bin/lsh-make-seed -o /var/spool/lsh/yarrow-seed-file - fi + hostKey = mkOption { + default = "/etc/lsh/host-key"; + description = '' + Path to the server's private key. Note that this key must + have been created, e.g., using "lsh-keygen --server | + lsh-writekey --server", so that you can run lshd. + ''; + }; - if ! test -f "${hostKey}" - then - ${lsh}/bin/lsh-keygen --server | \ - ${lsh}/bin/lsh-writekey --server -o "${hostKey}" - fi -end script + syslog = mkOption { + default = true; + description = ''Whether to enable syslog output.''; + }; -respawn ${lsh}/sbin/lshd --daemonic \ - --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ - -p ${toString portNumber} \ - ${if interfaces == [] then "" - else (concatStrings (map (i: "--interface=\"${i}\"") - interfaces))} \ - -h "${hostKey}" \ - ${if !syslog then "--no-syslog" else ""} \ - ${if passwordAuthentication then "--password" else "--no-password" } \ - ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ - ${if rootLogin then "--root-login" else "--no-root-login" } \ - ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \ - ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ - ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ - ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ - --subsystems=${concatStringsSep "," - (map (pair: (head pair) + "=" + - (head (tail pair))) - subsystems)} -''; + passwordAuthentication = mkOption { + default = true; + description = ''Whether to enable password authentication.''; + }; + + publicKeyAuthentication = mkOption { + default = true; + description = ''Whether to enable public key authentication.''; + }; + + rootLogin = mkOption { + default = false; + description = ''Whether to enable remote root login.''; + }; + + loginShell = mkOption { + default = null; + description = '' + If non-null, override the default login shell with the + specified value. + ''; + example = "/nix/store/xyz-bash-10.0/bin/bash10"; + }; + + srpKeyExchange = mkOption { + default = false; + description = '' + Whether to enable SRP key exchange and user authentication. + ''; + }; + + tcpForwarding = mkOption { + default = true; + description = ''Whether to enable TCP/IP forwarding.''; + }; + + x11Forwarding = mkOption { + default = true; + description = ''Whether to enable X11 forwarding.''; + }; + + subsystems = mkOption { + default = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; + description = '' + List of subsystem-path pairs, where the head of the pair + denotes the subsystem name, and the tail denotes the path to + an executable implementing it. + ''; + }; + }; + }; + }; +in + +###### implementation + +let + + inherit (pkgs) lsh; + inherit (pkgs.lib) concatStrings concatStringsSep head tail; + + lshdConfig = config.services.lshd; + + nssModules = config.system.nssModules.list; + + nssModulesPath = config.system.nssModules.path; +in + +mkIf config.services.lshd.enable { + require = [ + options + ]; + + services = { + extraJobs = [{ + name = "lshd"; + + job = with lshdConfig; '' + description "GNU lshd SSH2 daemon" + + start on network-interfaces/started + stop on network-interfaces/stop + + env LD_LIBRARY_PATH=${nssModulesPath} + + start script + test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh + test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh + + if ! test -f /var/spool/lsh/yarrow-seed-file + the + ${lsh}/bin/lsh-make-seed -o /var/spool/lsh/yarrow-seed-file + fi + + if ! test -f "${hostKey}" + then + ${lsh}/bin/lsh-keygen --server | \ + ${lsh}/bin/lsh-writekey --server -o "${hostKey}" + fi + end script + + respawn ${lsh}/sbin/lshd --daemonic \ + --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ + -p ${toString portNumber} \ + ${if interfaces == [] then "" + else (concatStrings (map (i: "--interface=\"${i}\"") + interfaces))} \ + -h "${hostKey}" \ + ${if !syslog then "--no-syslog" else ""} \ + ${if passwordAuthentication then "--password" else "--no-password" } \ + ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ + ${if rootLogin then "--root-login" else "--no-root-login" } \ + ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \ + ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ + ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ + ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ + --subsystems=${concatStringsSep "," + (map (pair: (head pair) + "=" + + (head (tail pair))) + subsystems)} + ''; +} + ]; + }; } diff --git a/upstart-jobs/lvm.nix b/upstart-jobs/lvm.nix index d860224685e7..1d16da59befc 100644 --- a/upstart-jobs/lvm.nix +++ b/upstart-jobs/lvm.nix @@ -1,30 +1,41 @@ -{modprobe, lvm2, devicemapper}: +{pkgs, config, ...}: + +###### implementation + +let + modprobe = config.system.sbin.modprobe; + +in + { - name = "lvm"; - - job = " -start on udev -#start on new-devices -script + services = { + extraJobs = [{ + name = "lvm"; + + job = '' + start on udev + #start on new-devices - # Load the device mapper. - ${modprobe}/sbin/modprobe dm_mod || true + script - ${devicemapper}/sbin/dmsetup mknodes - # Scan for block devices that might contain LVM physical volumes - # and volume groups. - ${lvm2}/sbin/vgscan --mknodes + # Load the device mapper. + ${modprobe}/sbin/modprobe dm_mod || true - # Make all logical volumes on all volume groups available, i.e., - # make them appear in /dev. - ${lvm2}/sbin/vgchange --available y + ${pkgs.devicemapper}/sbin/dmsetup mknodes + # Scan for block devices that might contain LVM physical volumes + # and volume groups. + ${pkgs.lvm2}/sbin/vgscan --mknodes - initctl emit new-devices - -end script - - "; + # Make all logical volumes on all volume groups available, i.e., + # make them appear in /dev. + ${pkgs.lvm2}/sbin/vgchange --available y + initctl emit new-devices + + end script + ''; + }]; + }; } diff --git a/upstart-jobs/maintenance-shell.nix b/upstart-jobs/maintenance-shell.nix index 9e2acdaa0f5f..8481f4283f50 100644 --- a/upstart-jobs/maintenance-shell.nix +++ b/upstart-jobs/maintenance-shell.nix @@ -1,19 +1,24 @@ -{bash}: +{pkgs, config, ...}: + +###### implementation { - name = "maintenance-shell"; - - job = " -start on maintenance -start on stalled - -script - exec < /dev/tty1 > /dev/tty1 2>&1 - echo \"\" - echo \"<<< MAINTENANCE SHELL >>>\" - echo \"\" - exec ${bash}/bin/sh -end script - "; - + services = { + extraJobs = [{ + name = "maintenance-shell"; + + job = '' + start on maintenance + start on stalled + + script + exec < /dev/tty1 > /dev/tty1 2>&1 + echo \"\" + echo \"<<< MAINTENANCE SHELL >>>\" + echo \"\" + exec ${pkgs.bash}/bin/sh + end script + ''; + }]; + }; } diff --git a/upstart-jobs/mingetty.nix b/upstart-jobs/mingetty.nix index 8f50ea5c9db2..c04d47061e9f 100644 --- a/upstart-jobs/mingetty.nix +++ b/upstart-jobs/mingetty.nix @@ -1,10 +1,74 @@ -{mingetty, ttyNumber, loginProgram}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + mingetty = { + + ttys = mkOption { + default = [1 2 3 4 5 6]; + description = " + The list of tty (virtual console) devices on which to start a + login prompt. + "; + }; + + waitOnMounts = mkOption { + default = false; + description = " + Whether the login prompts on the virtual consoles will be + started before or after all file systems have been mounted. By + default we don't wait, but if for example your /home is on a + separate partition, you may want to turn this on. + "; + }; + + greetingLine = mkOption { + default = ''<<< Welcome to NixOS (\m) - Kernel \r (\l) >>>''; + description = " + Welcome line printed by mingetty. + "; + }; + + helpLine = mkOption { + default = ""; + description = " + Help line printed by mingetty below the welcome line. + Used by the installation CD to give some hints on + how to proceed. + "; + }; + + }; + }; + }; +in + +###### implementation + +let + ttyNumbers = config.services.mingetty.ttys; + loginProgram = "${pkgs.pam_login}/bin/login"; + inherit (pkgs) mingetty; + +in { - name = "tty" + toString ttyNumber; - job = " - start on udev - stop on shutdown - respawn ${mingetty}/sbin/mingetty --loginprog=${loginProgram} --noclear tty${toString ttyNumber} - "; + require = [ + options + ]; + + services = { + extraJobs = map (ttyNumber : { + name = "tty" + toString ttyNumber; + job = " + start on udev + stop on shutdown + respawn ${mingetty}/sbin/mingetty --loginprog=${loginProgram} --noclear tty${toString ttyNumber} + "; + }) ttyNumbers; + }; } diff --git a/upstart-jobs/mysql.nix b/upstart-jobs/mysql.nix index 6756891321b6..2ecaa6df4cad 100644 --- a/upstart-jobs/mysql.nix +++ b/upstart-jobs/mysql.nix @@ -1,4 +1,49 @@ -{pkgs, config}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + mysql = { + enable = mkOption { + default = false; + description = " + Whether to enable the MySQL server. + "; + }; + + port = mkOption { + default = "3306"; + description = "Port of MySQL"; + }; + + user = mkOption { + default = "mysql"; + description = "User account under which MySQL runs"; + }; + + dataDir = mkOption { + default = "/var/mysql"; + description = "Location where MySQL stores its table files"; + }; + + logError = mkOption { + default = "/var/log/mysql_err.log"; + description = "Location of the MySQL error logfile"; + }; + + pidDir = mkOption { + default = "/var/run/mysql"; + description = "Location of the file which stores the PID of the MySQL server"; + }; + }; + }; + }; +in + +###### implementation let @@ -14,39 +59,51 @@ let in -{ - name = "mysql"; - - users = [ - { name = "mysql"; - description = "MySQL server user"; - } + +mkIf config.services.mysql.enable { + require = [ + options ]; - extraPath = [mysql]; - - job = '' - description "MySQL server" + users = { + extraUsers = [ + { name = "mysql"; + description = "MySQL server user"; + } + ]; + }; - stop on shutdown + services = { + extraJobs = [{ + name = "mysql"; + - start script - if ! test -e ${cfg.dataDir}; then - mkdir -m 0700 -p ${cfg.dataDir} - chown -R ${cfg.user} ${cfg.dataDir} - ${mysql}/bin/mysql_install_db ${mysqldOptions} - fi + extraPath = [mysql]; + + job = '' + description "MySQL server" - mkdir -m 0700 -p ${cfg.pidDir} - chown -R ${cfg.user} ${cfg.pidDir} - end script + stop on shutdown - respawn ${mysql}/bin/mysqld ${mysqldOptions} + start script + if ! test -e ${cfg.dataDir}; then + mkdir -m 0700 -p ${cfg.dataDir} + chown -R ${cfg.user} ${cfg.dataDir} + ${mysql}/bin/mysql_install_db ${mysqldOptions} + fi - stop script - pid=$(cat ${pidFile}) - kill "$pid" - ${mysql}/bin/mysql_waitpid "$pid" 1000 - end script - ''; + mkdir -m 0700 -p ${cfg.pidDir} + chown -R ${cfg.user} ${cfg.pidDir} + end script + + respawn ${mysql}/bin/mysqld ${mysqldOptions} + + stop script + pid=$(cat ${pidFile}) + kill "$pid" + ${mysql}/bin/mysql_waitpid "$pid" 1000 + end script + ''; + }]; + }; } diff --git a/upstart-jobs/network-interfaces.nix b/upstart-jobs/network-interfaces.nix index 61469fffbd6d..40803639331c 100644 --- a/upstart-jobs/network-interfaces.nix +++ b/upstart-jobs/network-interfaces.nix @@ -1,7 +1,11 @@ -{nettools, modprobe, wirelesstools, bash, writeText, config}: +{pkgs, config, ...}: + +###### implementation let + inherit (pkgs) nettools wirelesstools bash writeText; + cfg = config.networking; # !!! use XML @@ -10,91 +14,96 @@ let subnetMasks = map (i: if i ? subnetMask then i.subnetMask else "default") cfg.interfaces; essids = map (i: if i ? essid then i.essid else "default") cfg.interfaces; wepKeys = map (i: if i ? wepKey then i.wepKey else "nokey") cfg.interfaces; + modprobe = config.system.sbin.modprobe; in + { - name = "network-interfaces"; - - job = '' - start on udev - stop on shutdown - - start script - export PATH=${modprobe}/sbin:$PATH - modprobe af_packet || true - - for i in $(cd /sys/class/net && ls -d *); do - echo "Bringing up network device $i..." - ${nettools}/sbin/ifconfig $i up || true - done - - # Configure the manually specified interfaces. - names=(${toString names}) - ipAddresses=(${toString ipAddresses}) - subnetMasks=(${toString subnetMasks}) - essids=(${toString essids}) - wepKeys=(${toString wepKeys}) - - for ((n = 0; n < ''${#names[*]}; n++)); do - name=''${names[$n]} - ipAddress=''${ipAddresses[$n]} - subnetMask=''${subnetMasks[$n]} - essid=''${essids[$n]} - wepKey=''${wepKeys[$n]} - - # Set wireless networking stuff. - if test "$essid" != default; then - ${wirelesstools}/sbin/iwconfig "$name" essid "$essid" || true - fi - - if test "$wepKey" != nokey; then - ${wirelesstools}/sbin/iwconfig "$name" key "$(cat "$wepKey")" || true - fi - - # Set IP address / netmask. - if test "$ipAddress" != dhcp; then - echo "Configuring interface $name..." - extraFlags= - if test "$subnetMask" != default; then - extraFlags="$extraFlags netmask $subnetMask" - fi - ${nettools}/sbin/ifconfig "$name" "$ipAddress" $extraFlags || true - fi - - done - - # Set the nameservers. - if test -n "${toString cfg.nameservers}"; then - rm -f /etc/resolv.conf - if test -n "${cfg.domain}"; then - echo "domain ${cfg.domain}" >> /etc/resolv.conf - fi - for i in ${toString cfg.nameservers}; do - echo "nameserver $i" >> /etc/resolv.conf - done - fi - - # Set the default gateway. - if test -n "${cfg.defaultGateway}"; then - ${nettools}/sbin/route add default gw "${cfg.defaultGateway}" || true - fi - - # Run any user-specified commands. - ${bash}/bin/sh ${writeText "local-net-cmds" cfg.localCommands} || true - - end script - - # Hack: Upstart doesn't yet support what we want: a service that - # doesn't have a running process associated with it. - respawn sleep 100000 - - stop script - for i in $(cd /sys/class/net && ls -d *); do - echo "Taking down network device $i..." - ${nettools}/sbin/ifconfig $i down || true - done - end script - ''; - + services = { + extraJobs = [{ + name = "network-interfaces"; + + job = '' + start on udev + stop on shutdown + + start script + export PATH=${modprobe}/sbin:$PATH + modprobe af_packet || true + + for i in $(cd /sys/class/net && ls -d *); do + echo "Bringing up network device $i..." + ${nettools}/sbin/ifconfig $i up || true + done + + # Configure the manually specified interfaces. + names=(${toString names}) + ipAddresses=(${toString ipAddresses}) + subnetMasks=(${toString subnetMasks}) + essids=(${toString essids}) + wepKeys=(${toString wepKeys}) + + for ((n = 0; n < ''${#names[*]}; n++)); do + name=''${names[$n]} + ipAddress=''${ipAddresses[$n]} + subnetMask=''${subnetMasks[$n]} + essid=''${essids[$n]} + wepKey=''${wepKeys[$n]} + + # Set wireless networking stuff. + if test "$essid" != default; then + ${wirelesstools}/sbin/iwconfig "$name" essid "$essid" || true + fi + + if test "$wepKey" != nokey; then + ${wirelesstools}/sbin/iwconfig "$name" key "$(cat "$wepKey")" || true + fi + + # Set IP address / netmask. + if test "$ipAddress" != dhcp; then + echo "Configuring interface $name..." + extraFlags= + if test "$subnetMask" != default; then + extraFlags="$extraFlags netmask $subnetMask" + fi + ${nettools}/sbin/ifconfig "$name" "$ipAddress" $extraFlags || true + fi + + done + + # Set the nameservers. + if test -n "${toString cfg.nameservers}"; then + rm -f /etc/resolv.conf + if test -n "${cfg.domain}"; then + echo "domain ${cfg.domain}" >> /etc/resolv.conf + fi + for i in ${toString cfg.nameservers}; do + echo "nameserver $i" >> /etc/resolv.conf + done + fi + + # Set the default gateway. + if test -n "${cfg.defaultGateway}"; then + ${nettools}/sbin/route add default gw "${cfg.defaultGateway}" || true + fi + + # Run any user-specified commands. + ${bash}/bin/sh ${writeText "local-net-cmds" cfg.localCommands} || true + + end script + + # Hack: Upstart doesn't yet support what we want: a service that + # doesn't have a running process associated with it. + respawn sleep 100000 + + stop script + for i in $(cd /sys/class/net && ls -d *); do + echo "Taking down network device $i..." + ${nettools}/sbin/ifconfig $i down || true + done + end script + ''; + }]; + }; } diff --git a/upstart-jobs/new-proposal/synergyc.nix b/upstart-jobs/new-proposal/synergyc.nix deleted file mode 100644 index 57da073cd75e..000000000000 --- a/upstart-jobs/new-proposal/synergyc.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ path, thisConfig, config, lib, pkgs, upstartHelpers } : with upstartHelpers; { - options = { - description = "synergy client lets you use a shared keyboard, mouse and clipboard"; - screenName = mkOption { - default = ""; - description = " - use screen-name instead the hostname to identify - ourselfs to the server. - "; - apply = x: "-n '${x}'"; - }; - address = mkOption { - default = ""; - description = "server address to connect to"; - }; - }; - jobs = [ ( rec { - name = "synergyc"; - - # TODO start only when X Server has started as well - job = " -description \"${name}\" - -start on network-interfaces/started -stop on network-interfaces/stop - -exec ${pkgs.synergy}/bin/synergyc -f ${configV "screenName"} ${configV "address"} - "; - -} ) ]; -} diff --git a/upstart-jobs/new-proposal/synergys.nix b/upstart-jobs/new-proposal/synergys.nix deleted file mode 100644 index 8c320a07d6f0..000000000000 --- a/upstart-jobs/new-proposal/synergys.nix +++ /dev/null @@ -1,69 +0,0 @@ -{ path, thisConfig, config, lib, pkgs, upstartHelpers } : with upstartHelpers; { - options = { - description = "synergy client lets you use a shared keyboard, mouse and clipboard"; - - configuration = mkOption { - description = " - The synergy server configuration file - "; - }; - screenName = mkOption { - default = ""; - description = " - use screen-name instead the hostname to identify - this screen in the configuration. - "; - apply = x: "-n '${x}'"; - }; - address = mkOption { - default = ""; - description = "listen for clients on the given address"; - apply = x: "-a '${x}'"; - }; - }; - - jobs = - [ ( rec { - name = "synergys"; - - extraEtc = [ (autoGeneratedEtcFile { name = name + ".conf"; content = thisConfig.configuration; }) ]; - - # TODO start only when X Server has started as well - job = " -description \"${name}\" - -start on network-interfaces/started and xserver/started -stop on network-interfaces/stop or xserver/stop - -exec ${pkgs.synergy}/bin/synergys -c /etc/${name}.conf -f ${configV "address"} ${configV "screenName"} - "; - -} ) ]; -} - -/* Example configuration - -section: screens - laptop: - dm: - win: -end -section: aliases - laptop: - 192.168.5.5 - dm: - 192.168.5.78 - win: - 192.168.5.54 -end -section: links - laptop: - left = dm - dm: - right = laptop - left = win - win: - right = dm -end - -*/ diff --git a/upstart-jobs/new-proposal/tightvnc.nix b/upstart-jobs/new-proposal/tightvnc.nix deleted file mode 100644 index 054828a5230a..000000000000 --- a/upstart-jobs/new-proposal/tightvnc.nix +++ /dev/null @@ -1,89 +0,0 @@ -{ path, thisConfig, config, lib, pkgs, upstartHelpers } : with upstartHelpers; rec { - options = { - description = "tightvnc vnc server (share virtual desktop over network"; - - geometry = mkOption { - default = "-geometry 800x600"; - example = "800x600"; - description = '' - size of virtual screen - ''; - apply = x : "-geometry '${x}'"; - }; - depth = mkOption { - default = "-depth 24"; - description = '' - use screen-name instead the hostname to identify - this screen in the configuration. - value must be something between 8 and 32 - ''; - apply = x: "-depth '${x}'"; - check = x: (__lessThan x 33) && (7 __lessThan x); # not yet used - }; - display = mkOption { - default = ":8"; - example = 8; - description = "display to use"; - apply = x: ":${builtins.toString x}"; - }; - authFile = mkOption { - default = "-auth /etc/tightvnc-pwd"; - description = '' - The file containing authentication passwords. - Can be created using vncpasswd - ''; - apply = x: "-auth '${x}'"; - check = __pathExists; - }; - httpPort = mkOption { - default = "-httpport 5900"; - example = 5901; - description = "http port to listen to (Java applet remote interface)"; - apply = x: "-httpport '${builtins.toString x}'"; - }; - desktopName = mkOption { - description = '' - Set VNC desktop name ("x11" by default) - ''; - apply = x: "-desktop '${x}'"; - }; - viewOnly = mkOption { - default = ""; - description = '' - Don't accept keboard and pointer events from clients. All clients will be able to see - the desktop but won't be able to control it. - ''; - apply = x: "-viewonly '${x}'"; - }; - interface = mkOption { - default = ""; - description = '' - Listen for client connections only on the network interface with given ipaddr - ''; - apply = x: "-interface '${x}'"; - }; - extras = mkOption { - default = ""; - description = '' - additional params, see man Xvnc - ''; - }; - }; - - jobs = if (lib.getAttr ["services" "xfs" "enable"] false config) != true - then abort "you need to enable xfs services = { xfs = { enable = true; }; } within your nixos/configuration.nix file" - else - [ ( rec { - name = "tightvnc"; - - job = " -description \"${name}\" - -start on network-interfaces/started and xserver/started -stop on network-interfaces/stop or xserver/stop - -exec ${pkgs.tightvnc}/bin/Xvnc -fp unix/:7100 ${lib.concatStringsSep " " (lib.mapIf (x : x != "description") configV (__attrNames options ) ) } - "; -} ) ]; -} -# diff --git a/upstart-jobs/nix.nix b/upstart-jobs/nix.nix new file mode 100644 index 000000000000..c46b721a2a02 --- /dev/null +++ b/upstart-jobs/nix.nix @@ -0,0 +1,227 @@ +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + + nix = { + + maxJobs = mkOption { + default = 1; + example = 2; + description = " + This option defines the maximum number of jobs that Nix will try + to build in parallel. The default is 1. You should generally + set it to the number of CPUs in your system (e.g., 2 on a Athlon + 64 X2). + "; + }; + + useChroot = mkOption { + default = false; + example = true; + description = " + If set, Nix will perform builds in a chroot-environment that it + will set up automatically for each build. This prevents + impurities in builds by disallowing access to dependencies + outside of the Nix store. + "; + }; + + extraOptions = mkOption { + default = ""; + example = " + gc-keep-outputs = true + gc-keep-derivations = true + "; + description = " + This option allows to append lines to nix.conf. + "; + }; + + distributedBuilds = mkOption { + default = false; + description = " + Whether to distribute builds to the machines listed in + . + "; + }; + + buildMachines = mkOption { + example = [ + { hostName = "voila.labs.cs.uu.nl"; + sshUser = "nix"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "powerpc-darwin"; + maxJobs = 1; + } + { hostName = "linux64.example.org"; + sshUser = "buildfarm"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "x86_64-linux"; + maxJobs = 2; + } + ]; + description = " + This option lists the machines to be used if distributed + builds are enabled (see + ). Nix will perform + derivations on those machines via SSh by copying the inputs to + the Nix store on the remote machine, starting the build, then + copying the output back to the local Nix store. Each element + of the list should be an attribute set containing the + machine's host name (hostname), the user + name to be used for the SSH connection + (sshUser), the Nix system type + (system, e.g., + \"i686-linux\"), the maximum number of jobs + to be run in parallel on that machine + (maxJobs), and the path to the SSH private + key to be used to connect (sshKey). The + SSH private key should not have a passphrase, and the + corresponding public key should be added to + ~sshUser/authorized_keys + on the remote machine. + "; + }; + + proxy = mkOption { + default = ""; + description = " + This option specifies the proxy to use for fetchurl. The real effect + is just exporting http_proxy, https_proxy and ftp_proxy with that + value. + "; + example = "http://127.0.0.1:3128"; + }; + + # Environment variables for running Nix. + envVars = mkOption { + internal = true; + default = ""; + description = " + Define the environment variables used by nix to + "; + + merge = pkgs.lib.mergeStringOption; + + # other option should be used to define the content instead of using + # the apply function. + apply = conf: '' + export NIX_CONF_DIR=/nix/etc/nix + + # Enable the copy-from-other-stores substituter, which allows builds + # to be sped up by copying build results from remote Nix stores. To + # do this, mount the remote file system on a subdirectory of + # /var/run/nix/remote-stores. + export NIX_OTHER_STORES=/var/run/nix/remote-stores/*/nix + + '' + # */ + (if config.nix.distributedBuilds then + '' + export NIX_BUILD_HOOK=${config.environment.nix}/libexec/nix/build-remote.pl + export NIX_REMOTE_SYSTEMS=/etc/nix.machines + export NIX_CURRENT_LOAD=/var/run/nix/current-load + '' + else "") + + + (if config.nix.proxy != "" then + '' + export http_proxy=${config.nix.proxy} + export https_proxy=${config.nix.proxy} + export ftp_proxy=${config.nix.proxy} + '' + else "") + + conf; + }; + + + services = { + pulseaudio = { + enable = mkOption { + default = false; + description = '' + Whether to enable the PulseAudio system-wide audio server. + Note that the documentation recommends running PulseAudio + daemons per-user rather than system-wide on desktop machines. + ''; + }; + + logLevel = mkOption { + default = "notice"; + example = "debug"; + description = '' + A string denoting the log level: one of + error, warn, + notice, info, + or debug. + ''; + }; + }; + }; + }; + }; +in + +###### implementation + +let + binsh = config.system.build.binsh; + nixEnvVars = config.nix.envVars; + inherit (pkgs) nix; +in + +{ + require = [ + options + ]; + + environment = { + etc = [ + { # Nix configuration. + source = + let + # Tricky: if we're using a chroot for builds, then we need + # /bin/sh in the chroot (our own compromise to purity). + # However, since /bin/sh is a symlink to some path in the + # Nix store, which furthermore has runtime dependencies on + # other paths in the store, we need the closure of /bin/sh + # in `build-chroot-dirs' - otherwise any builder that uses + # /bin/sh won't work. + refs = pkgs.writeReferencesToFile binsh; + in + pkgs.runCommand "nix.conf" {} '' + binshDeps=$(for i in $(cat ${refs}); do if test -d $i; then echo $i; fi; done) + cat > $out < /dev/null 2>&1 + end script + ''; + }]; + }; +} diff --git a/upstart-jobs/nscd.nix b/upstart-jobs/nscd.nix index c88c219c63b8..fe89cdc5646b 100644 --- a/upstart-jobs/nscd.nix +++ b/upstart-jobs/nscd.nix @@ -1,35 +1,44 @@ -{glibc, nssModulesPath}: +{pkgs, config, ...}: + +###### implementation + +let + nssModulesPath = config.system.nssModules.path; +in { - name = "nscd"; - - users = [ - { name = "nscd"; - uid = (import ../system/ids.nix).uids.nscd; - description = "Name service cache daemon user"; - } - ]; - - job = " -description \"Name Service Cache Daemon\" - -start on startup -stop on shutdown - -env LD_LIBRARY_PATH=${nssModulesPath} - -start script - - mkdir -m 0755 -p /var/run/nscd - mkdir -m 0755 -p /var/db/nscd - - rm -f /var/db/nscd/* # for testing - -end script - -# !!! -d turns on debug info which probably makes nscd slower -# 2>/dev/null is to make it shut up -respawn ${glibc}/sbin/nscd -f ${./nscd.conf} -d 2> /dev/null - "; - + services = { + extraJobs = [{ + name = "nscd"; + + users = [ + { name = "nscd"; + uid = (import ../system/ids.nix).uids.nscd; + description = "Name service cache daemon user"; + } + ]; + + job = '' + description \"Name Service Cache Daemon\" + + start on startup + stop on shutdown + + env LD_LIBRARY_PATH=${nssModulesPath} + + start script + + mkdir -m 0755 -p /var/run/nscd + mkdir -m 0755 -p /var/db/nscd + + rm -f /var/db/nscd/* # for testing + + end script + + # !!! -d turns on debug info which probably makes nscd slower + # 2>/dev/null is to make it shut up + respawn ${pkgs.glibc}/sbin/nscd -f ${./nscd.conf} -d 2> /dev/null + ''; + }]; + }; } diff --git a/upstart-jobs/ntpd.nix b/upstart-jobs/ntpd.nix index 4bfcfe115cbb..9716ce3f308d 100644 --- a/upstart-jobs/ntpd.nix +++ b/upstart-jobs/ntpd.nix @@ -1,52 +1,101 @@ -{ntp, modprobe, glibc, writeText, servers}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + ntp = { + + enable = mkOption { + default = true; + description = " + Whether to synchronise your machine's time using the NTP + protocol. + "; + }; + + servers = mkOption { + default = [ + "0.pool.ntp.org" + "1.pool.ntp.org" + "2.pool.ntp.org" + ]; + description = " + The set of NTP servers from which to synchronise. + "; + }; + + }; + }; + }; +in + +###### implementation let + inherit (pkgs) writeText ntp; + stateDir = "/var/lib/ntp"; ntpUser = "ntp"; - config = writeText "ntp.conf" '' + servers = config.services.ntp.servers; + + modprobe = config.system.sbin.modprobe; + + configFile = writeText "ntp.conf" '' driftfile ${stateDir}/ntp.drift ${toString (map (server: "server " + server + "\n") servers)} ''; - ntpFlags = "-c ${config} -u ${ntpUser}:nogroup -i ${stateDir}"; + ntpFlags = "-c ${configFile} -u ${ntpUser}:nogroup -i ${stateDir}"; in -{ - name = "ntpd"; - - users = [ - { name = ntpUser; - uid = (import ../system/ids.nix).uids.ntp; - description = "NTP daemon user"; - home = stateDir; - } + +mkIf config.services.ntp.enable { + require = [ + options ]; - - job = '' - description "NTP daemon" - start on ip-up - stop on ip-down - stop on shutdown + services = { + extraJobs = [{ - start script + name = "ntpd"; + + users = [ + { name = ntpUser; + uid = (import ../system/ids.nix).uids.ntp; + description = "NTP daemon user"; + home = stateDir; + } + ]; + + job = '' + description "NTP daemon" - mkdir -m 0755 -p ${stateDir} - chown ${ntpUser} ${stateDir} + start on ip-up + stop on ip-down + stop on shutdown - # Needed to run ntpd as an unprivileged user. - ${modprobe}/sbin/modprobe capability || true + start script - ${ntp}/bin/ntpd -q -g ${ntpFlags} + mkdir -m 0755 -p ${stateDir} + chown ${ntpUser} ${stateDir} - end script + # Needed to run ntpd as an unprivileged user. + ${modprobe}/sbin/modprobe capability || true - respawn ${ntp}/bin/ntpd -n ${ntpFlags} - ''; - + ${ntp}/bin/ntpd -q -g ${ntpFlags} + + end script + + respawn ${ntp}/bin/ntpd -n ${ntpFlags} + ''; + }]; + }; } diff --git a/upstart-jobs/openfire.nix b/upstart-jobs/openfire.nix index 45338c793e7d..365d34a5b264 100644 --- a/upstart-jobs/openfire.nix +++ b/upstart-jobs/openfire.nix @@ -1,7 +1,36 @@ -{pkgs, config}: +{pkgs, config, ...}: -assert config.services.openfire.usePostgreSQL -> config.services.postgresql.enable; +###### interface let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + openfire = { + enable = mkOption { + default = false; + description = " + Whether to enable OpenFire XMPP server. + "; + }; + usePostgreSQL = mkOption { + default = true; + description = " + Whether you use PostgreSQL service for your storage back-end. + "; + }; + }; + }; + }; +in + +###### implementation + +# FIXME (see xfs) +# if (!(config.services.openfire.usePostgreSQL -> config.services.postgresql.enable)) then throw "openfire assertion failed" else +let + inherit (pkgs) jre openfire coreutils which gnugrep gawk gnused; + startDependency = if config.services.openfire.usePostgreSQL then "postgresql" else @@ -10,26 +39,35 @@ let else "network-interfaces"; in -with pkgs; -{ - name = "openfire"; - job = '' - description "OpenFire XMPP server" - start on ${startDependency}/started - stop on shutdown +mkIf config.services.openfire.enable { + require = [ + options + ]; - script - export PATH=${jre}/bin:${openfire}/bin:${coreutils}/bin:${which}/bin:${gnugrep}/bin:${gawk}/bin:${gnused}/bin - export HOME=/tmp - mkdir /var/log/openfire || true - mkdir /etc/openfire || true - for i in ${openfire}/conf.inst/*; do - if ! test -f /etc/openfire/$(basename $i); then - cp $i /etc/openfire/ - fi - done - openfire start - end script - ''; + + services = { + extraJobs = [{ + name = "openfire"; + job = '' + description "OpenFire XMPP server" + + start on ${startDependency}/started + stop on shutdown + + script + export PATH=${jre}/bin:${openfire}/bin:${coreutils}/bin:${which}/bin:${gnugrep}/bin:${gawk}/bin:${gnused}/bin + export HOME=/tmp + mkdir /var/log/openfire || true + mkdir /etc/openfire || true + for i in ${openfire}/conf.inst/*; do + if ! test -f /etc/openfire/$(basename $i); then + cp $i /etc/openfire/ + fi + done + openfire start + end script + ''; + }]; + }; } diff --git a/upstart-jobs/portmap.nix b/upstart-jobs/portmap.nix index 18ff06dc1af4..0c3368545c2b 100644 --- a/upstart-jobs/portmap.nix +++ b/upstart-jobs/portmap.nix @@ -1,35 +1,70 @@ -{ makePortmap }: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + portmap = { + enable = mkOption { + default = false; + description = '' + Whether to enable `portmap', an ONC RPC directory service + notably used by NFS and NIS, and which can be queried + using the rpcinfo(1) command. + ''; + }; + }; + }; + }; +in + +###### implementation let uid = (import ../system/ids.nix).uids.portmap; gid = (import ../system/ids.nix).gids.portmap; in -{ - name = "portmap"; - - users = [ - { name = "portmap"; - inherit uid; - description = "portmap daemon user"; - home = "/var/empty"; - } + +mkIf config.services.portmap.enable { + + require = [ + options ]; - groups = [ - { name = "portmap"; - inherit gid; - } - ]; - job = - let portmap = makePortmap { daemonUID = uid; daemonGID = gid; }; - in - '' -description "ONC RPC portmap" + users = { + extraUsers = [ + { name = "portmap"; + inherit uid; + description = "portmap daemon user"; + home = "/var/empty"; + } + ]; -start on network-interfaces/started -stop on network-interfaces/stop + extraGroups = [ + { name = "portmap"; + inherit gid; + } + ]; + }; -respawn ${portmap}/sbin/portmap -''; - + services = { + extraJobs = [{ + name = "portmap"; + + + job = + let portmap = pkgs.makePortmap { daemonUID = uid; daemonGID = gid; }; + in + '' + description "ONC RPC portmap" + + start on network-interfaces/started + stop on network-interfaces/stop + + respawn ${portmap}/sbin/portmap + ''; + }]; + }; } diff --git a/upstart-jobs/postfix.nix b/upstart-jobs/postfix.nix index e72f12ea8421..8db43693b946 100644 --- a/upstart-jobs/postfix.nix +++ b/upstart-jobs/postfix.nix @@ -1,4 +1,154 @@ -{config, pkgs} : +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + postfix = { + enable = mkOption { + default = false; + description =" + Whether to run the Postfix mail server. + "; + }; + user = mkOption { + default = "postfix"; + description = " + How to call postfix user (must be used only for postfix). + "; + }; + group = mkOption { + default = "postfix"; + description = " + How to call postfix group (must be used only for postfix). + "; + }; + setgidGroup = mkOption { + default = "postdrop"; + description = " + How to call postfix setgid group (for postdrop). Should + be uniquely used group. + "; + }; + networks = mkOption { + default = null; + example = ["192.168.0.1/24"]; + description = " + Net masks for trusted - allowed to relay mail to third parties - + hosts. Leave empty to use mynetworks_style configuration or use + default (localhost-only). + "; + }; + networksStyle = mkOption { + default = ""; + description = " + Name of standard way of trusted network specification to use, + leave blank if you specify it explicitly or if you want to use + default (localhost-only). + "; + }; + hostname = mkOption { + default = ""; + description =" + Hostname to use. Leave blank to use just the hostname of machine. + It should be FQDN. + "; + }; + domain = mkOption { + default = ""; + description =" + Domain to use. Leave blank to use hostname minus first component. + "; + }; + origin = mkOption { + default = ""; + description =" + Origin to use in outgoing e-mail. Leave blank to use hostname. + "; + }; + destination = mkOption { + default = null; + example = ["localhost"]; + description = " + Full (!) list of domains we deliver locally. Leave blank for + acceptable Postfix default. + "; + }; + relayDomains = mkOption { + default = null; + example = ["localdomain"]; + description = " + List of domains we agree to relay to. Default is the same as + destination. + "; + }; + relayHost = mkOption { + default = ""; + description = " + Mail relay for outbound mail. + "; + }; + lookupMX = mkOption { + default = false; + description = " + Whether relay specified is just domain whose MX must be used. + "; + }; + postmasterAlias = mkOption { + default = "root"; + description = " + Who should receive postmaster e-mail. + "; + }; + rootAlias = mkOption { + default = ""; + description = " + Who should receive root e-mail. Blank for no redirection. + "; + }; + extraAliases = mkOption { + default = ""; + description = " + Additional entries to put verbatim into aliases file. + "; + }; + + sslCert = mkOption { + default = ""; + description = " + SSL certificate to use. + "; + }; + sslCACert = mkOption { + default = ""; + description = " + SSL certificate of CA. + "; + }; + sslKey = mkOption { + default = ""; + description =" + SSL key to use. + "; + }; + + recipientDelimiter = mkOption { + default = ""; + example = "+"; + description = " + Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test + "; + }; + + }; + }; + }; +in + +###### implementation + let startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; @@ -103,62 +253,76 @@ let mainCfFile = pkgs.writeText "postfix-main.cf" mainCf; in -{ - name = "postfix"; - users = [ - { name = user; - description = "Postfix mail server user"; - uid = idList.uids.postfix; - group = group; - } + +mkIf config.services.postfix.enable { + require = [ + options ]; - groups = [ - { name = group; - gid = idList.gids.postfix; - } - { name = setgidGroup; - gid = idList.gids.postdrop; - } - ]; - - - # I copy _lots_ of shipped configuration filed - # that can be left as is. I am afraid the exact - # will list slightly change in next Postfix - # release, so listing them all one-by-one in an - # accurate way is unlikely to be better. - job = '' - description "Postfix mail server job" - - start on ${startingDependency}/started - stop on never - - script - if ! [ -d /var/spool/postfix ]; then - ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue - fi - - ${pkgs.coreutils}/bin/chown -R ${user}.${group} /var/postfix - ${pkgs.coreutils}/bin/chown -R ${user}.${setgidGroup} /var/postfix/queue - ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue - ${pkgs.coreutils}/bin/chown root.root /var/spool/mail - ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail - - ln -sf ${pkgs.postfix}/share/postfix/conf/* /var/postfix/conf - - ln -sf ${aliasesFile} /var/postfix/conf/aliases - ln -sf ${mainCfFile} /var/postfix/conf/main.cf - - ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases - - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start - end script - ''; - - extraEtc = [ - { source = "/var/postfix/conf"; + environment = { + etc = [{ + source = "/var/postfix/conf"; target = "postfix"; - } - ]; + }]; + }; + + users = { + extraUsers = [ + { name = user; + description = "Postfix mail server user"; + uid = idList.uids.postfix; + group = group; + } + ]; + + extraGroups = [ + { name = group; + gid = idList.gids.postfix; + } + { name = setgidGroup; + gid = idList.gids.postdrop; + } + ]; + }; + + services = { + extraJobs = [{ + name = "postfix"; + + + # I copy _lots_ of shipped configuration filed + # that can be left as is. I am afraid the exact + # will list slightly change in next Postfix + # release, so listing them all one-by-one in an + # accurate way is unlikely to be better. + job = '' + description "Postfix mail server job" + + start on ${startingDependency}/started + stop on never + + script + if ! [ -d /var/spool/postfix ]; then + ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue + fi + + ${pkgs.coreutils}/bin/chown -R ${user}.${group} /var/postfix + ${pkgs.coreutils}/bin/chown -R ${user}.${setgidGroup} /var/postfix/queue + ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue + ${pkgs.coreutils}/bin/chown root.root /var/spool/mail + ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail + + ln -sf ${pkgs.postfix}/share/postfix/conf/* /var/postfix/conf + + ln -sf ${aliasesFile} /var/postfix/conf/aliases + ln -sf ${mainCfFile} /var/postfix/conf/main.cf + + ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases + + ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start + end script + ''; + + }]; + }; } diff --git a/upstart-jobs/postgresql.nix b/upstart-jobs/postgresql.nix index a37780678fc9..77cf1a582e9b 100644 --- a/upstart-jobs/postgresql.nix +++ b/upstart-jobs/postgresql.nix @@ -1,4 +1,72 @@ -{pkgs, config}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + postgresql = { + enable = mkOption { + default = false; + description = " + Whether to run PostgreSQL. + "; + }; + port = mkOption { + default = "5432"; + description = " + Port for PostgreSQL. + "; + }; + logDir = mkOption { + default = "/var/log/postgresql"; + description = " + Log directory for PostgreSQL. + "; + }; + dataDir = mkOption { + default = "/var/db/postgresql"; + description = " + Data directory for PostgreSQL. + "; + }; + subServices = mkOption { + default = []; + description = " + Subservices list. As it is already implememnted, + here is an interface... + "; + }; + authentication = mkOption { + default = '' + # Generated file; do not edit! + local all all ident sameuser + host all all 127.0.0.1/32 md5 + host all all ::1/128 md5 + ''; + description = " + Hosts (except localhost), who you allow to connect. + "; + }; + allowedHosts = mkOption { + default = []; + description = " + Hosts (except localhost), who you allow to connect. + "; + }; + authMethod = mkOption { + default = " ident sameuser "; + description = " + How to authorize users. + Note: ident needs absolute trust to all allowed client hosts."; + }; + }; + }; + }; +in + +###### implementation let @@ -13,36 +81,47 @@ let in -{ - name = "postgresql"; - - users = [ - { name = "postgres"; - description = "PostgreSQL server user"; - } +mkIf config.services.postgresql.enable { + require = [ + options ]; - groups = [ - { name = "postgres"; } - ]; - extraPath = [postgresql]; + users = { + extraUsers = [ + { name = "postgres"; + description = "PostgreSQL server user"; + } + ]; - job = '' - description "PostgreSQL server" + extraGroups = [ + { name = "postgres"; } + ]; + }; - start on ${startDependency}/started - stop on shutdown - - start script - if ! test -e ${cfg.dataDir}; then - mkdir -m 0700 -p ${cfg.dataDir} - chown -R postgres ${cfg.dataDir} - ${run} -c '${postgresql}/bin/initdb -D ${cfg.dataDir} -U root' - fi - cp -f ${pkgs.writeText "pg_hba.conf" cfg.authentication} ${cfg.dataDir}/pg_hba.conf - end script + services = { + extraJobs = [{ + name = "postgresql"; - respawn ${run} -c '${postgresql}/bin/postgres -D ${cfg.dataDir}' - ''; + extraPath = [postgresql]; + + job = '' + description "PostgreSQL server" + + start on ${startDependency}/started + stop on shutdown + + start script + if ! test -e ${cfg.dataDir}; then + mkdir -m 0700 -p ${cfg.dataDir} + chown -R postgres ${cfg.dataDir} + ${run} -c '${postgresql}/bin/initdb -D ${cfg.dataDir} -U root' + fi + cp -f ${pkgs.writeText "pg_hba.conf" cfg.authentication} ${cfg.dataDir}/pg_hba.conf + end script + + respawn ${run} -c '${postgresql}/bin/postgres -D ${cfg.dataDir}' + ''; + }]; + }; } diff --git a/upstart-jobs/samba.nix b/upstart-jobs/samba.nix index b1371c6f0f5e..90f09a3bdd65 100644 --- a/upstart-jobs/samba.nix +++ b/upstart-jobs/samba.nix @@ -1,4 +1,26 @@ -{pkgs, samba, glibc}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + samba = { + + enable = mkOption { + default = false; + description = " + Whether to enable the samba server. (to communicate with, and provide windows shares) + "; + }; + + }; + }; + }; +in + +###### implementation let @@ -7,52 +29,65 @@ let smbConfig = ./smb.conf ; + inherit (pkgs) samba; + in -{ - name = "samba"; - users = [ - { name = user; - description = "Samba service user"; - group = group; - } - ]; - groups = [ - { name = group; - } + +mkIf config.services.samba.enable { + require = [ + options ]; - - job = " -description \"Samba Service\" + users = { + extraUsers = [ + { name = user; + description = "Samba service user"; + group = group; + } + ]; + + extraGroups = [ + { name = group; + } + ]; + }; -start on network-interfaces/started -stop on network-interfaces/stop + services = { + extraJobs = [{ + name = "samba"; + job = '' -start script + description "Samba Service" - if ! test -d /home/smbd ; then - mkdir -p /home/smbd - chown ${user} /home/smbd - chmod a+rwx /home/smbd - fi + start on network-interfaces/started + stop on network-interfaces/stop - if ! test -d /var/samba ; then - mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd - fi + start script - ${samba}/sbin/nmbd -D -s ${smbConfig} & - ${samba}/sbin/smbd -D -s ${smbConfig} & - ${samba}/sbin/winbindd -B -s ${smbConfig} & + if ! test -d /home/smbd ; then + mkdir -p /home/smbd + chown ${user} /home/smbd + chmod a+rwx /home/smbd + fi - ln -fs ${smbConfig} /var/samba/config + if ! test -d /var/samba ; then + mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd + fi -end script + ${samba}/sbin/nmbd -D -s ${smbConfig} & + ${samba}/sbin/smbd -D -s ${smbConfig} & + ${samba}/sbin/winbindd -B -s ${smbConfig} & -respawn ${samba}/sbin/nmbd -D -s ${smbConfig} &; ${samba}/sbin/smbd -D -s ${smbConfig} &; ${samba}/sbin/winbindd -B & + ln -fs ${smbConfig} /var/samba/config - "; + end script + respawn ${samba}/sbin/nmbd -D -s ${smbConfig} &; ${samba}/sbin/smbd -D -s ${smbConfig} &; ${samba}/sbin/winbindd -B & + + ''; + }]; + }; } diff --git a/upstart-jobs/sshd.nix b/upstart-jobs/sshd.nix index e9b916e81d33..03dc9f47a9c3 100644 --- a/upstart-jobs/sshd.nix +++ b/upstart-jobs/sshd.nix @@ -1,14 +1,66 @@ -{ writeText, openssh, glibc, xauth -, nssModulesPath -, forwardX11, allowSFTP, permitRootLogin, gatewayPorts -}: +{pkgs, config, ...}: -assert permitRootLogin == "yes" || - permitRootLogin == "without-password" || - permitRootLogin == "forced-commands-only" || - permitRootLogin == "no"; - +###### interface let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + sshd = { + + enable = mkOption { + default = false; + description = " + Whether to enable the Secure Shell daemon, which allows secure + remote logins. + "; + }; + + forwardX11 = mkOption { + default = true; + description = " + Whether to enable sshd to forward X11 connections. + "; + }; + + allowSFTP = mkOption { + default = true; + description = " + Whether to enable the SFTP subsystem in the SSH daemon. This + enables the use of commands such as sftp and + sshfs. + "; + }; + + permitRootLogin = mkOption { + default = "yes"; + description = " + Whether the root user can login using ssh. Valid options + are yes, without-password, + forced-commands-only or + no + "; + }; + + gatewayPorts = mkOption { + default = "no"; + description = " + Specifies whether remote hosts are allowed to connect to ports forwarded for the client. See man sshd_conf. + "; + }; + }; + }; + }; + +###### implementation + + inherit (pkgs) writeText openssh; + + cfg = (config.services.sshd); + + nssModules = config.system.nssModules.list; + + nssModulesPath = config.system.nssModules.path; sshdConfig = writeText "sshd_config" '' @@ -16,55 +68,70 @@ let UsePAM yes - ${if forwardX11 then " + ${if cfg.forwardX11 then " X11Forwarding yes - XAuthLocation ${xauth}/bin/xauth + XAuthLocation ${pkgs.xlibs.xauth}/bin/xauth " else " X11Forwarding no "} - ${if allowSFTP then " + ${if cfg.allowSFTP then " Subsystem sftp ${openssh}/libexec/sftp-server " else " "} - PermitRootLogin ${permitRootLogin} - GatewayPorts ${gatewayPorts} + PermitRootLogin ${cfg.permitRootLogin} + GatewayPorts ${cfg.gatewayPorts} ''; sshdUid = (import ../system/ids.nix).uids.sshd; + assertion = cfg.permitRootLogin == "yes" || + cfg.permitRootLogin == "without-password" || + cfg.permitRootLogin == "forced-commands-only" || + cfg.permitRootLogin == "no"; + in -{ - name = "sshd"; - users = [ - { name = "sshd"; - uid = (import ../system/ids.nix).uids.sshd; - description = "SSH privilege separation user"; - home = "/var/empty"; - } +mkIf config.services.sshd.enable { + require = [ + options ]; - - job = '' - description "SSH server" - start on network-interfaces/started - stop on network-interfaces/stop + users = { + extraUsers = [ + { name = "sshd"; + uid = (import ../system/ids.nix).uids.sshd; + description = "SSH privilege separation user"; + home = "/var/empty"; + } + ]; + }; - env LD_LIBRARY_PATH=${nssModulesPath} + services = { + extraJobs = [{ + name = "sshd"; - start script - mkdir -m 0755 -p /etc/ssh + job = '' + description "SSH server" - if ! test -f /etc/ssh/ssh_host_dsa_key; then - ${openssh}/bin/ssh-keygen -t dsa -b 1024 -f /etc/ssh/ssh_host_dsa_key -N "" - fi - end script + start on network-interfaces/started + stop on network-interfaces/stop - respawn ${openssh}/sbin/sshd -D -h /etc/ssh/ssh_host_dsa_key -f ${sshdConfig} - ''; - + env LD_LIBRARY_PATH=${nssModulesPath} + + start script + mkdir -m 0755 -p /etc/ssh + + if ! test -f /etc/ssh/ssh_host_dsa_key; then + ${openssh}/bin/ssh-keygen -t dsa -b 1024 -f /etc/ssh/ssh_host_dsa_key -N "" + fi + end script + + respawn ${openssh}/sbin/sshd -D -h /etc/ssh/ssh_host_dsa_key -f ${sshdConfig} + ''; + }]; + }; } diff --git a/upstart-jobs/swap.nix b/upstart-jobs/swap.nix index cd640b5060e4..5b6b70e362f9 100644 --- a/upstart-jobs/swap.nix +++ b/upstart-jobs/swap.nix @@ -1,7 +1,13 @@ -{lib, utillinux, swapDevices}: +{pkgs, config, ...}: + +###### implementation let + inherit (pkgs) utillinux lib; + + swapDevices = config.swapDevices; + devicesByPath = map (x: x.device) (lib.filter (x: x ? device) swapDevices); @@ -10,35 +16,39 @@ let in + { - name = "swap"; - - job = " -start on startup -start on new-devices - -script - for device in ${toString devicesByPath}; do - ${utillinux}/sbin/swapon \"$device\" || true - done - - for label in ${toString devicesByLabel}; do - ${utillinux}/sbin/swapon -L \"$label\" || true - done - - # Remove swap devices not listed in swapDevices. - # !!! disabled because it doesn't work with labels - #for used in $(cat /proc/swaps | grep '^/' | sed 's/ .*//'); do - # found= - # for device in $ {toString swapDevices}; do - # if test \"$used\" = \"$device\"; then found=1; fi - # done - # if test -z \"$found\"; then - # ${utillinux}/sbin/swapoff \"$used\" || true - # fi - #done - -end script - "; - + services = { + extraJobs = [{ + name = "swap"; + + job = " + start on startup + start on new-devices + + script + for device in ${toString devicesByPath}; do + ${utillinux}/sbin/swapon \"$device\" || true + done + + for label in ${toString devicesByLabel}; do + ${utillinux}/sbin/swapon -L \"$label\" || true + done + + # Remove swap devices not listed in swapDevices. + # !!! disabled because it doesn't work with labels + #for used in $(cat /proc/swaps | grep '^/' | sed 's/ .*//'); do + # found= + # for device in $ {toString swapDevices}; do + # if test \"$used\" = \"$device\"; then found=1; fi + # done + # if test -z \"$found\"; then + # ${utillinux}/sbin/swapoff \"$used\" || true + # fi + #done + + end script + "; + }]; + }; } diff --git a/upstart-jobs/swraid.nix b/upstart-jobs/swraid.nix index 5cf7d82e3833..a0a25efa3548 100644 --- a/upstart-jobs/swraid.nix +++ b/upstart-jobs/swraid.nix @@ -1,36 +1,44 @@ -{modprobe, mdadm}: +{pkgs, config, ...}: + +###### implementation let tempConf = "/var/run/mdadm.conf"; + modprobe = config.system.sbin.modprobe; + inherit (pkgs) mdadm; in { - name = "swraid"; - - job = " -start on udev -#start on new-devices - -script - - # Load the necessary RAID personalities. - # !!! hm, doesn't the kernel load these automatically? - for mod in raid0 raid1 raid5; do - ${modprobe}/sbin/modprobe $mod || true - done - - # Scan /proc/partitions for RAID devices. - ${mdadm}/sbin/mdadm --examine --brief --scan -c partitions > ${tempConf} - - # Activate each device found. - ${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan - - initctl emit new-devices - -end script - - "; + services = { + extraJobs = [{ + name = "swraid"; + + job = '' + start on udev + #start on new-devices + + script + + # Load the necessary RAID personalities. + # !!! hm, doesn't the kernel load these automatically? + for mod in raid0 raid1 raid5; do + ${modprobe}/sbin/modprobe $mod || true + done + + # Scan /proc/partitions for RAID devices. + ${mdadm}/sbin/mdadm --examine --brief --scan -c partitions > ${tempConf} + + # Activate each device found. + ${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan + + initctl emit new-devices + + end script + + ''; + }]; + }; } diff --git a/upstart-jobs/syslogd.nix b/upstart-jobs/syslogd.nix index c255eb0d9a89..bc293936982b 100644 --- a/upstart-jobs/syslogd.nix +++ b/upstart-jobs/syslogd.nix @@ -1,8 +1,32 @@ -{sysklogd, writeText, config}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + + syslogd = { + + tty = mkOption { + default = 10; + description = " + The tty device on which syslogd will print important log + messages. + "; + }; + + }; + }; + }; +in + +###### implementation let - syslogConf = writeText "syslog.conf" '' + syslogConf = pkgs.writeText "syslog.conf" '' kern.warning;*.err;authpriv.none /dev/tty10 # Send emergency messages to all users. @@ -22,16 +46,24 @@ let in { - name = "syslogd"; - - job = '' - description "Syslog daemon" - - start on udev - stop on shutdown + require = [ + options + ]; - env TZ=${config.time.timeZone} - - respawn ${sysklogd}/sbin/syslogd -n -f ${syslogConf} - ''; + services = { + extraJobs = [{ + name = "syslogd"; + + job = '' + description "Syslog daemon" + + start on udev + stop on shutdown + + env TZ=${config.time.timeZone} + + respawn ${pkgs.sysklogd}/sbin/syslogd -n -f ${syslogConf} + ''; + }]; + }; } diff --git a/upstart-jobs/tomcat.nix b/upstart-jobs/tomcat.nix index 233da6abe384..f714e2387f3a 100644 --- a/upstart-jobs/tomcat.nix +++ b/upstart-jobs/tomcat.nix @@ -1,109 +1,175 @@ -args: with args; +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + tomcat = { + enable = mkOption { + default = false; + description = "Whether to enable Apache Tomcat"; + }; + + baseDir = mkOption { + default = "/var/tomcat"; + description = "Location where Tomcat stores configuration files, webapplications and logfiles"; + }; + + user = mkOption { + default = "tomcat"; + description = "User account under which Apache Tomcat runs."; + }; + + deployFrom = mkOption { + default = ""; + description = "Location where webapplications are stored. Leave empty to use the baseDir."; + }; + + javaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns Apache Tomcat"; + }; + + catalinaOpts = mkOption { + default = ""; + description = "Parameters to pass to the Java Virtual Machine which spawns the Catalina servlet container"; + }; + + sharedLibFrom = mkOption { + default = ""; + description = "Location where shared libraries are stored. Leave empty to use the baseDir."; + }; + + commonLibFrom = mkOption { + default = ""; + description = "Location where common libraries are stored. Leave empty to use the baseDir."; + }; + + contextXML = mkOption { + default = ""; + description = "Location of the context.xml to use. Leave empty to use the default."; + }; + }; + }; + }; +in + +###### implementation let cfg = config.services.tomcat; in -{ - name = "tomcat"; - - groups = [ - { name = "tomcat"; - gid = (import ../system/ids.nix).gids.tomcat; - } +mkIf config.services.tomcat.enable { + require = [ + options ]; - - users = [ - { name = "tomcat"; - uid = (import ../system/ids.nix).uids.tomcat; - description = "Tomcat user"; - home = "/homeless-shelter"; - } - ]; - - job = '' - description "Apache Tomcat server" - start on network-interface/started - stop on network-interfaces/stop - - start script - # Create initial state data + services = { + extraJobs = [{ + name = "tomcat"; + + groups = [ + { name = "tomcat"; + gid = (import ../system/ids.nix).gids.tomcat; + } + ]; + + users = [ + { name = "tomcat"; + uid = (import ../system/ids.nix).uids.tomcat; + description = "Tomcat user"; + home = "/homeless-shelter"; + } + ]; + + job = '' + description "Apache Tomcat server" + + start on network-interface/started + stop on network-interfaces/stop - if ! test -d ${cfg.baseDir} - then - mkdir -p ${cfg.baseDir}/webapps - mkdir -p ${cfg.baseDir}/shared - mkdir -p ${cfg.baseDir}/lib - cp -av ${pkgs.tomcat6}/{conf,temp,logs} ${cfg.baseDir} - fi - - # Deploy context.xml - - if test "${cfg.contextXML}" = "" - then - cp ${pkgs.tomcat6}/conf/context.xml.default ${cfg.baseDir}/conf/context.xml - else - cp ${cfg.contextXML} ${cfg.baseDir}/conf/context.xml - fi - - # Deploy all webapplications - - if ! test "${cfg.deployFrom}" = "" - then - rm -rf ${cfg.baseDir}/webapps - mkdir -p ${cfg.baseDir}/webapps - for i in ${cfg.deployFrom}/* + start script + # Create initial state data + + if ! test -d ${cfg.baseDir} + then + mkdir -p ${cfg.baseDir}/webapps + mkdir -p ${cfg.baseDir}/shared + mkdir -p ${cfg.baseDir}/lib + cp -av ${pkgs.tomcat6}/{conf,temp,logs} ${cfg.baseDir} + fi + + # Deploy context.xml + + if test "${cfg.contextXML}" = "" + then + cp ${pkgs.tomcat6}/conf/context.xml.default ${cfg.baseDir}/conf/context.xml + else + cp ${cfg.contextXML} ${cfg.baseDir}/conf/context.xml + fi + + # Deploy all webapplications + + if ! test "${cfg.deployFrom}" = "" + then + rm -rf ${cfg.baseDir}/webapps + mkdir -p ${cfg.baseDir}/webapps + for i in ${cfg.deployFrom}/* + do + cp -rL $i ${cfg.baseDir}/webapps + done + fi + + # Fix permissions + + chown -R ${cfg.user} ${cfg.baseDir} + + for i in `find ${cfg.baseDir} -type d` do - cp -rL $i ${cfg.baseDir}/webapps + chmod -v 755 $i + done + + for i in `find ${cfg.baseDir} -type f` + do + chmod -v 644 $i done - fi - - # Fix permissions - - chown -R ${cfg.user} ${cfg.baseDir} - - for i in `find ${cfg.baseDir} -type d` - do - chmod -v 755 $i - done - - for i in `find ${cfg.baseDir} -type f` - do - chmod -v 644 $i - done - # Deploy all common libraries - - rm -rf ${cfg.baseDir}/lib/* - - if test "${cfg.commonLibFrom}" = "" - then - commonLibFrom="${pkgs.tomcat6}/lib"; - else - commonLibFrom="${cfg.commonLibFrom}"; - fi - - for i in $commonLibFrom/*.jar - do - ln -s $i ${cfg.baseDir}/lib - done + # Deploy all common libraries + + rm -rf ${cfg.baseDir}/lib/* + + if test "${cfg.commonLibFrom}" = "" + then + commonLibFrom="${pkgs.tomcat6}/lib"; + else + commonLibFrom="${cfg.commonLibFrom}"; + fi + + for i in $commonLibFrom/*.jar + do + ln -s $i ${cfg.baseDir}/lib + done - # Deploy all shared libraries + # Deploy all shared libraries + + if ! test "${cfg.sharedLibFrom}" = "" + then + rm -f ${cfg.baseDir}/shared/lib + ln -s ${cfg.sharedLibFrom} ${cfg.baseDir}/shared/lib + fi + + end script - if ! test "${cfg.sharedLibFrom}" = "" - then - rm -f ${cfg.baseDir}/shared/lib - ln -s ${cfg.sharedLibFrom} ${cfg.baseDir}/shared/lib - fi - - end script - - respawn ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh; sleep 1000d' - - stop script - echo "Stopping tomcat..." - CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${pkgs.tomcat6}/bin/shutdown.sh - end script - ''; + respawn ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c 'CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} JAVA_OPTS="${cfg.javaOpts}" CATALINA_OPTS="${cfg.catalinaOpts}" ${pkgs.tomcat6}/bin/startup.sh; sleep 1000d' + + stop script + echo "Stopping tomcat..." + CATALINA_BASE=${cfg.baseDir} JAVA_HOME=${pkgs.jdk} ${pkgs.su}/bin/su -s ${pkgs.bash}/bin/sh ${cfg.user} -c ${pkgs.tomcat6}/bin/shutdown.sh + end script + ''; + }]; + }; } diff --git a/upstart-jobs/tty-backgrounds.nix b/upstart-jobs/tty-backgrounds.nix index 604085308709..825874aaeed4 100644 --- a/upstart-jobs/tty-backgrounds.nix +++ b/upstart-jobs/tty-backgrounds.nix @@ -1,11 +1,100 @@ -{stdenv, splashutils, backgrounds}: +{pkgs, config, ...}: -rec { - name = "tty-backgrounds"; +###### interface +let + inherit (pkgs.lib) mkOption mkIf; - unpackTheme = theme: import ../helpers/unpack-theme.nix { - inherit stdenv theme; + options = { + services = { + ttyBackgrounds = { + + enable = mkOption { + default = true; + description = " + Whether to enable graphical backgrounds for the virtual consoles. + "; + }; + + defaultTheme = mkOption { + default = pkgs.fetchurl { + #url = http://www.bootsplash.de/files/themes/Theme-BabyTux.tar.bz2; + url = http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/distfiles/Theme-BabyTux.tar.bz2; + md5 = "a6d89d1c1cff3b6a08e2f526f2eab4e0"; + }; + description = " + The default theme for the virtual consoles. Themes can be found + at . + "; + }; + + defaultSpecificThemes = mkOption { + default = [ + /* + { tty = 6; + theme = pkgs.fetchurl { # Yeah! + url = http://www.bootsplash.de/files/themes/Theme-Pativo.tar.bz2; + md5 = "9e13beaaadf88d43a5293e7ab757d569"; + }; + } + */ + { tty = 10; + theme = pkgs.fetchurl { + #url = http://www.bootsplash.de/files/themes/Theme-GNU.tar.bz2; + url = http://www.mirrorservice.org/sites/www.ibiblio.org/gentoo/distfiles/Theme-GNU.tar.bz2; + md5 = "61969309d23c631e57b0a311102ef034"; + }; + } + ]; + description = " + This option sets specific themes for virtual consoles. If you + just want to set themes for additional consoles, use + . + "; + }; + + specificThemes = mkOption { + default = [ + ]; + description = " + This option allows you to set specific themes for virtual + consoles. + "; + }; + }; + }; }; +in + +###### implementation + +let + inherit (pkgs) stdenv; + kernelPackages = config.boot.kernelPackages; + splashutils = kernelPackages.splashutils; + requiredTTYs = config.requiredTTYs; + backgrounds = + + let + + specificThemes = + config.services.ttyBackgrounds.defaultSpecificThemes + ++ config.services.ttyBackgrounds.specificThemes; + + overridenTTYs = map (x: x.tty) specificThemes; + + # Use the default theme for all the mingetty ttys and for the + # syslog tty, except those for which a specific theme is + # specified. + defaultTTYs = + pkgs.lib.filter (x: !(pkgs.lib.elem x overridenTTYs)) requiredTTYs; + + in + (map (ttyNumber: { + tty = ttyNumber; + theme = config.services.ttyBackgrounds.defaultTheme; + }) defaultTTYs) + ++ specificThemes; + themesUnpacked = stdenv.mkDerivation { name = "splash-themes"; @@ -15,46 +104,71 @@ rec { themes = map (x: if x ? theme then (unpackTheme x.theme) else "default") backgrounds; }; - extraEtc = [ - { source = themesUnpacked; - target = "splash"; - } + unpackTheme = theme: import ../helpers/unpack-theme.nix { + inherit stdenv theme; + }; + + + +in + +# FIXME see xfs +# assert splashutils != null; + +mkIf (config.services.ttyBackgrounds.enable && kernelPackages.splashutils != null) { + require = [ + options ]; - job = '' - start on udev - start script + environment = { + etc = [ + { source = themesUnpacked; + target = "splash"; + } + ]; + }; - # Critical: tell the kernel where to find splash_helper. It calls - # this program every time we switch between consoles. - helperProcFile=${splashutils.helperProcFile} - if test -e /proc/sys/fbcondecor; then helperProcFile=/proc/sys/fbcondecor; fi - echo ${splashutils}/${splashutils.helperName} > $helperProcFile - # For each console... - for tty in ${toString (map (x: x.tty) backgrounds)}; do - # Make sure that the console exists. - echo -n "" > /dev/tty$tty + services = { + extraJobs = [ rec { + name = "tty-backgrounds"; - # Set the theme as determined by tty-backgrounds-combine.sh - # above. - theme=$(readlink ${themesUnpacked}/$tty) - ${splashutils}/${splashutils.controlName} --tty $tty -c setcfg -t $theme || true - ${splashutils}/${splashutils.controlName} --tty $tty -c setpic -t $theme || true - ${splashutils}/${splashutils.controlName} --tty $tty -c on || true - done + job = '' + start on udev - end script + start script - respawn sleep 10000 # !!! Hack + # Critical: tell the kernel where to find splash_helper. It calls + # this program every time we switch between consoles. + helperProcFile=${splashutils.helperProcFile} + if test -e /proc/sys/fbcondecor; then helperProcFile=/proc/sys/fbcondecor; fi + echo ${splashutils}/${splashutils.helperName} > $helperProcFile - stop script - # Disable the theme on each console. - for tty in ${toString (map (x: x.tty) backgrounds)}; do - ${splashutils}/${splashutils.controlName} --tty $tty -c off || true - done - end script - ''; - + # For each console... + for tty in ${toString (map (x: x.tty) backgrounds)}; do + # Make sure that the console exists. + echo -n "" > /dev/tty$tty + + # Set the theme as determined by tty-backgrounds-combine.sh + # above. + theme=$(readlink ${themesUnpacked}/$tty) + ${splashutils}/${splashutils.controlName} --tty $tty -c setcfg -t $theme || true + ${splashutils}/${splashutils.controlName} --tty $tty -c setpic -t $theme || true + ${splashutils}/${splashutils.controlName} --tty $tty -c on || true + done + + end script + + respawn sleep 10000 # !!! Hack + + stop script + # Disable the theme on each console. + for tty in ${toString (map (x: x.tty) backgrounds)}; do + ${splashutils}/${splashutils.controlName} --tty $tty -c off || true + done + end script + ''; + }]; + }; } diff --git a/upstart-jobs/udev.nix b/upstart-jobs/udev.nix index 4662adde222d..4765f29176e6 100644 --- a/upstart-jobs/udev.nix +++ b/upstart-jobs/udev.nix @@ -1,18 +1,66 @@ -{ stdenv, writeText, substituteAll, cleanSource, udev, procps, firmwareDirs, modprobe -, extraUdevPkgs ? [] -, config -}: +{pkgs, config, ...}: + +###### interface +let + inherit (pkgs.lib) mkOption mkIf; + + options = { + services = { + udev = { + + addFirmware = mkOption { + default = []; + example = ["/mnt/big-storage/firmware/"]; + description = " + To specify firmware that is not too spread to ensure + a package, or have an interactive process of extraction + and cannot be redistributed. + "; + merge = pkgs.lib.mergeListOption; + }; + + addUdevPkgs = mkOption { + default = []; + description = " + List of packages containing udev rules. + "; + merge = pkgs.lib.mergeListOption; + }; + + sndMode = mkOption { + default = "0600"; + example = "0666"; + description = " + Permissions for /dev/snd/*, in case you have multiple + logged in users or if the devices belong to root for + some reason. + "; + }; + }; + }; + }; +in + +###### implementation let + inherit (pkgs) substituteAll stdenv writeText udev procps; + cfg = config.services.udev; + firmwareLoader = substituteAll { src = ./udev-firmware-loader.sh; path = "${stdenv.coreutils}/bin"; isExecutable = true; inherit firmwareDirs; }; + + firmwareDirs = config.services.udev.addFirmware; + extraUdevPkgs = config.services.udev.addUdevPkgs; + + modprobe = config.system.sbin.modprobe; nixRules = writeText "90-nix.rules" '' @@ -86,55 +134,64 @@ let in { - name = "udev"; - - job = '' - start on startup - stop on shutdown - env UDEV_CONFIG_FILE=${conf} + require = [ + options + ]; - start script - echo "" > /proc/sys/kernel/hotplug + services = { + extraJobs = [{ + name = "udev"; + + job = '' + start on startup + stop on shutdown - # Get rid of possible old udev processes. - ${procps}/bin/pkill -u root "^udevd$" || true + env UDEV_CONFIG_FILE=${conf} - # Do the loading of additional stage 2 kernel modules. - # Maybe this isn't the best place... - for i in ${toString config.boot.kernelModules}; do - echo "Loading kernel module $i..." - ${modprobe}/sbin/modprobe $i || true - done + start script + echo "" > /proc/sys/kernel/hotplug - # Start udev. - ${udev}/sbin/udevd --daemon + # Get rid of possible old udev processes. + ${procps}/bin/pkill -u root "^udevd$" || true - # Let udev create device nodes for all modules that have already - # been loaded into the kernel (or for which support is built into - # the kernel). - if ! test -e ${devicesCreated}; then - ${udev}/sbin/udevadm trigger - ${udev}/sbin/udevadm settle # wait for udev to finish - touch ${devicesCreated} - fi + # Do the loading of additional stage 2 kernel modules. + # Maybe this isn't the best place... + for i in ${toString config.boot.kernelModules}; do + echo "Loading kernel module $i..." + ${modprobe}/sbin/modprobe $i || true + done - # Kill udev, let Upstart restart and monitor it. (This is nasty, - # but we have to run `udevadm trigger' first. Maybe we can use - # Upstart's `binary' keyword, but it isn't implemented yet.) - if ! ${procps}/bin/pkill -u root "^udevd$"; then - echo "couldn't stop udevd" - fi + # Start udev. + ${udev}/sbin/udevd --daemon - while ${procps}/bin/pgrep -u root "^udevd$"; do - sleep 1 - done + # Let udev create device nodes for all modules that have already + # been loaded into the kernel (or for which support is built into + # the kernel). + if ! test -e ${devicesCreated}; then + ${udev}/sbin/udevadm trigger + ${udev}/sbin/udevadm settle # wait for udev to finish + touch ${devicesCreated} + fi - initctl emit new-devices - end script + # Kill udev, let Upstart restart and monitor it. (This is nasty, + # but we have to run `udevadm trigger' first. Maybe we can use + # Upstart's `binary' keyword, but it isn't implemented yet.) + if ! ${procps}/bin/pkill -u root "^udevd$"; then + echo "couldn't stop udevd" + fi - respawn ${udev}/sbin/udevd - ''; + while ${procps}/bin/pgrep -u root "^udevd$"; do + sleep 1 + done - passthru = {inherit udevRules;}; + initctl emit new-devices + end script + + respawn ${udev}/sbin/udevd + ''; + + passthru = {inherit udevRules;}; + }]; + }; } diff --git a/upstart-jobs/vsftpd.nix b/upstart-jobs/vsftpd.nix index 01a509ea679a..22d11eab51bc 100644 --- a/upstart-jobs/vsftpd.nix +++ b/upstart-jobs/vsftpd.nix @@ -1,80 +1,120 @@ -{ vsftpd, anonymousUser -, anonymousUploadEnable, anonymousMkdirEnable, writeEnable -}: +{pkgs, config, ...}: -{ - name = "vsftpd"; +###### interface +let + inherit (pkgs.lib) mkOption mkIf; - groups = [ - { name = "ftp"; - gid = (import ../system/ids.nix).gids.ftp; - } + options = { + services = { + vsftpd = { + enable = mkOption { + default = false; + description = " + Whether to enable the vsftpd FTP server. + "; + }; + + anonymousUser = mkOption { + default = false; + description = " + Whether to enable the anonymous FTP user. + "; + }; + + writeEnable = mkOption { + default = false; + description = " + Whether any write activity is permitted to users. + "; + }; + + anonymousUploadEnable = mkOption { + default = false; + description = " + Whether any uploads are permitted to anonymous users. + "; + }; + + anonymousMkdirEnable = mkOption { + default = false; + description = " + Whether mkdir is permitted to anonymous users. + "; + }; + }; + }; + }; +in + +###### implementation + +let + + inherit (config.services.vsftpd) anonymousUser writeEnable anonymousUploadEnable anonymousMkdirEnable; + inherit (pkgs) vsftpd; + + yesNoOption = p : name : + "${name}=${if p then "YES" else "NO"}"; + +in + +mkIf config.services.vsftpd.enable { + require = [ + options ]; - - users = [ - { name = "vsftpd"; - uid = (import ../system/ids.nix).uids.vsftpd; - description = "VSFTPD user"; - home = "/homeless-shelter"; - } - ] ++ - (if anonymousUser then [ - { name = "ftp"; - uid = (import ../system/ids.nix).uids.ftp; - group = "ftp"; - description = "Anonymous ftp user"; - home = "/home/ftp"; - } - ] - else - []); - - job = " -description \"vsftpd server\" -start on network-interfaces/started -stop on network-interfaces/stop + users = { + extraUsers = [ + { name = "vsftpd"; + uid = (import ../system/ids.nix).uids.vsftpd; + description = "VSFTPD user"; + home = "/homeless-shelter"; + } + ] ++ pkgs.lib.optional anonymousUser + { name = "ftp"; + uid = (import ../system/ids.nix).uids.ftp; + group = "ftp"; + description = "Anonymous ftp user"; + home = "/home/ftp"; + }; -start script - cat > /etc/vsftpd.conf < /etc/vsftpd.conf <