* Converted modules that were still using the old (concrete syntax)

style of declaring Upstart jobs.  While at it, converted them to the
  current NixOS module style and improved some option descriptions.
  Hopefully I didn't break too much :-)

svn path=/nixos/trunk/; revision=17761
This commit is contained in:
Eelco Dolstra 2009-10-12 16:36:19 +00:00
parent 4a78ef25e7
commit e91d882a94
42 changed files with 3298 additions and 3520 deletions

View File

@ -1,15 +1,22 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
uid = config.ids.uids.pulseaudio; uid = config.ids.uids.pulseaudio;
gid = config.ids.gids.pulseaudio; gid = config.ids.gids.pulseaudio;
in
{
###### interface
options = { options = {
services = {
pulseaudio = { services.pulseaudio = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = '' description = ''
@ -29,61 +36,53 @@ let
or <literal>debug</literal>. or <literal>debug</literal>.
''; '';
}; };
}; };
}; };
};
in
###### implementation ###### implementation
config = mkIf config.services.pulseaudio.enable {
mkIf config.services.pulseaudio.enable { environment.systemPackages = [ pkgs.pulseaudio ];
require = [
options
];
environment = { users.extraUsers = singleton
systemPackages = [pkgs.pulseaudio];
};
users = {
extraUsers = [
{ name = "pulse"; { name = "pulse";
# For some reason, PulseAudio wants UID == GID. # For some reason, PulseAudio wants UID == GID.
uid = assert uid == gid; uid; uid = assert uid == gid; uid;
group = "pulse"; group = "pulse";
description = "PulseAudio system-wide daemon"; description = "PulseAudio system-wide daemon";
home = "/var/run/pulse"; home = "/var/run/pulse";
}
];
extraGroups = [
{ name = "pulse";
inherit gid;
}
];
}; };
services = { users.extraGroups = singleton
extraJobs = [{ { name = "pulse";
name = "pulseaudio"; inherit gid;
};
job = '' jobAttrs.pulseaudio =
description "PulseAudio system-wide server" { description = "PulseAudio system-wide server";
start on startup startOn = "startup";
stop on shutdown stopOn = "shutdown";
start script preStart =
''
test -d /var/run/pulse || \ test -d /var/run/pulse || \
( mkdir -p --mode 755 /var/run/pulse && \ ( mkdir -p --mode 755 /var/run/pulse && \
chown pulse:pulse /var/run/pulse ) chown pulse:pulse /var/run/pulse )
end script '';
respawn ${pkgs.pulseaudio}/bin/pulseaudio \ exec =
''
${pkgs.pulseaudio}/bin/pulseaudio \
--system --daemonize \ --system --daemonize \
--log-level="${config.services.pulseaudio.logLevel}" --log-level="${config.services.pulseaudio.logLevel}"
''; '';
}];
}; };
};
} }

View File

@ -1,8 +1,8 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### implementation ###### implementation
let let
inherit (pkgs.lib);
klogdCmd = "${pkgs.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";
@ -10,24 +10,20 @@ in
{ {
services = { jobAttrs.klogd =
extraJobs = [{ { description = "Kernel log daemon";
name = "klogd";
job = '' startOn = "syslogd";
description "Kernel log daemon" stopOn = "shutdown";
start on syslogd preStart =
stop on shutdown ''
start script
# !!! this hangs for some reason (it blocks reading from # !!! this hangs for some reason (it blocks reading from
# /proc/kmsg). # /proc/kmsg).
#${klogdCmd} -o #${klogdCmd} -o
end script
respawn ${klogdCmd} -n
''; '';
}];
exec = "${klogdCmd} -n";
}; };
} }

View File

@ -1,8 +1,9 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib; with pkgs.lib;
let let
startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces";
cfg = config.services.dovecot; cfg = config.services.dovecot;
@ -112,23 +113,18 @@ in
gid = config.ids.gids.dovecot; gid = config.ids.gids.dovecot;
}; };
services.extraJobs = singleton jobAttrs.dovecot =
{ name = "dovecot"; { description = "Dovecot IMAP/POP3 server";
job = startOn = "${startingDependency}/started";
preStart =
'' ''
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/mkdir -p /var/run/dovecot /var/run/dovecot/login
${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot ${pkgs.coreutils}/bin/chown -R ${cfg.user}.${cfg.group} /var/run/dovecot
end script
respawn ${pkgs.dovecot}/sbin/dovecot -F -c ${confFile}
''; '';
exec = "${pkgs.dovecot}/sbin/dovecot -F -c ${confFile}";
}; };
}; };

View File

@ -1,155 +1,9 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### interface with pkgs.lib;
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 let
startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces"; startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces";
cfg = config.services.postfix; cfg = config.services.postfix;
@ -157,8 +11,6 @@ let
group = cfg.group; group = cfg.group;
setgidGroup = cfg.setgidGroup; setgidGroup = cfg.setgidGroup;
optionalString = pkgs.lib.optionalString;
concatStringsSep = pkgs.lib.concatStringsSep;
mainCf = mainCf =
'' ''
queue_directory = /var/postfix/queue queue_directory = /var/postfix/queue
@ -172,53 +24,49 @@ let
+ optionalString (config.services.gw6c.enable || config.networking.nativeIPv6) ('' + optionalString (config.services.gw6c.enable || config.networking.nativeIPv6) (''
inet_protocols = all inet_protocols = all
'') '')
+ + (if cfg.networks != null then
(if cfg.networks!=null then ''
(''
mynetworks = ${concatStringsSep ", " cfg.networks} mynetworks = ${concatStringsSep ", " cfg.networks}
'') ''
else if (cfg.networksStyle != "") then else if cfg.networksStyle != "" then
('' ''
mynetworks_style = ${cfg.networksStyle} mynetworks_style = ${cfg.networksStyle}
'') ''
else else
# Postfix default is subnet, but let's play safe # Postfix default is subnet, but let's play safe
('' ''
mynetworks_style = host mynetworks_style = host
'') '')
) + optionalString (cfg.hostname != "") ''
+ optionalString (cfg.hostname != "") (''
myhostname = ${cfg.hostname} myhostname = ${cfg.hostname}
'') ''
+ optionalString (cfg.domain != "") ('' + optionalString (cfg.domain != "") ''
mydomain = ${cfg.domain} mydomain = ${cfg.domain}
'') ''
+ optionalString (cfg.origin != "") ('' + optionalString (cfg.origin != "") ''
myorigin = ${cfg.origin} myorigin = ${cfg.origin}
'') ''
+ optionalString (cfg.destination != null) ('' + optionalString (cfg.destination != null) ''
mydestination = ${concatStringsSep ", " cfg.destination} mydestination = ${concatStringsSep ", " cfg.destination}
'') ''
+ optionalString (cfg.relayDomains != null) ('' + optionalString (cfg.relayDomains != null) ''
relay_domains = ${concatStringsSep ", " cfg.relayDomains} relay_domains = ${concatStringsSep ", " cfg.relayDomains}
'') ''
+ '' + ''
local_recipient_maps = local_recipient_maps =
''
+ (''
relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then
cfg.relayHost cfg.relayHost
else else
"[" + cfg.relayHost + "]"} "[" + cfg.relayHost + "]"}
'')
+ (''
alias_maps = hash:/var/postfix/conf/aliases alias_maps = hash:/var/postfix/conf/aliases
mail_spool_directory = /var/spool/mail/ mail_spool_directory = /var/spool/mail/
setgid_group = ${setgidGroup} setgid_group = ${setgidGroup}
'') ''
+ optionalString (cfg.sslCert != "") ('' + optionalString (cfg.sslCert != "") ''
smtp_tls_CAfile = ${cfg.sslCACert} smtp_tls_CAfile = ${cfg.sslCACert}
smtp_tls_cert_file = ${cfg.sslCert} smtp_tls_cert_file = ${cfg.sslCert}
@ -234,17 +82,15 @@ let
recipientDelimiter = ${cfg.recipientDelimiter} recipientDelimiter = ${cfg.recipientDelimiter}
'') '';
;
aliases = aliases =
(optionalString (cfg.postmasterAlias != "") ('' optionalString (cfg.postmasterAlias != "") ''
postmaster: ${cfg.postmasterAlias} postmaster: ${cfg.postmasterAlias}
'')) ''
+ + optionalString (cfg.rootAlias != "") ''
(optionalString (cfg.rootAlias != "") (''
root: ${cfg.rootAlias} root: ${cfg.rootAlias}
'')) ''
+ cfg.extraAliases + cfg.extraAliases
; ;
@ -253,54 +99,194 @@ let
in in
mkIf config.services.postfix.enable { {
require = [
options
];
environment = { ###### interface
etc = [{
source = "/var/postfix/conf"; options = {
target = "postfix";
}]; services.postfix = {
enable = mkOption {
default = false;
description = "Whether to run the Postfix mail server.";
}; };
users = { user = mkOption {
extraUsers = [ default = "postfix";
description = "What to call the Postfix user (must be used only for postfix).";
};
group = mkOption {
default = "postfix";
description = "What to call the 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
";
};
};
};
###### implementation
config = mkIf config.services.postfix.enable {
environment.etc = singleton
{ source = "/var/postfix/conf";
target = "postfix";
};
users.extraUsers = singleton
{ name = user; { name = user;
description = "Postfix mail server user"; description = "Postfix mail server user";
uid = config.ids.uids.postfix; uid = config.ids.uids.postfix;
group = group; group = group;
} };
];
extraGroups = [ users.extraGroups =
{ name = group; [ { name = group;
gid = config.ids.gids.postfix; gid = config.ids.gids.postfix;
} }
{ name = setgidGroup; { name = setgidGroup;
gid = config.ids.gids.postdrop; gid = config.ids.gids.postdrop;
} }
]; ];
};
services = {
extraJobs = [{
name = "postfix";
jobAttrs.postfix =
# I copy _lots_ of shipped configuration filed # I copy _lots_ of shipped configuration filed
# that can be left as is. I am afraid the exact # that can be left as is. I am afraid the exact
# will list slightly change in next Postfix # will list slightly change in next Postfix
# release, so listing them all one-by-one in an # release, so listing them all one-by-one in an
# accurate way is unlikely to be better. # accurate way is unlikely to be better.
job = '' { description = "Postfix mail server";
description "Postfix mail server job"
start on ${startingDependency}/started startOn = "${startingDependency}/started";
stop on never
script script =
''
if ! [ -d /var/spool/postfix ]; then if ! [ -d /var/spool/postfix ]; then
${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
fi fi
@ -319,9 +305,10 @@ mkIf config.services.postfix.enable {
${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
end script ''; # */
'';
}];
}; };
};
} }

View File

@ -1,13 +1,21 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.autofs;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
autofs = { services.autofs = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "
@ -49,59 +57,43 @@ let
default = false; default = false;
description = "pass -d to automount and write log to /var/log/autofs"; description = "pass -d to automount and write log to /var/log/autofs";
}; };
}; };
}; };
};
###### implementation ###### implementation
inherit (pkgs) lib writeTextopenssh autofs5; config = mkIf cfg.enable {
cfg = (config.services.autofs); environment.etc = singleton
{ target = "auto.master";
modprobe = config.system.sbin.modprobe;
in
mkIf cfg.enable {
require = [
options
];
environment = {
etc =
[ {
target = "auto.master";
source = pkgs.writeText "auto.master" cfg.autoMaster; source = pkgs.writeText "auto.master" cfg.autoMaster;
}];
}; };
services = { jobAttrs.autofs =
extraJobs = [ { description = "Filesystem automounter";
{
name = "autofs";
# kernel module autofs supports kernel protocol v3 startOn = "network-interfaces/started";
# kernel module autofs4 supports kernel protocol v3, v4, v5 stopOn = "network-interfaces/stop";
job = ''
description "automatically mount filesystems"
start on network-interfaces/started environment =
stop on network-interfaces/stop { PATH = "${pkgs.nfsUtils}/sbin:${config.system.sbin.modprobe}/sbin";
};
PATH=${pkgs.nfsUtils}/sbin:${modprobe}/sbin preStart =
''
start script
modprobe autofs4 || true modprobe autofs4 || true
end script '';
script script =
''
${if cfg.debug then "exec &> /var/log/autofs" else ""} ${if cfg.debug then "exec &> /var/log/autofs" else ""}
${pkgs.autofs5}/sbin/automount -f -t ${builtins.toString cfg.timeout} ${if cfg.debug then "-d" else ""} "${pkgs.writeText "auto.master" cfg.autoMaster}" ${pkgs.autofs5}/sbin/automount -f -t ${builtins.toString cfg.timeout} ${if cfg.debug then "-d" else ""} "${pkgs.writeText "auto.master" cfg.autoMaster}"
end script
''; '';
}
];
}; };
};
} }

View File

@ -1,62 +1,57 @@
# Disnix server # Disnix server
{ config, pkgs, ... }: { config, pkgs, ... }:
###### interface with pkgs.lib;
let let
inherit (pkgs.lib) mkOption;
cfg = config.services.disnix;
in
{
###### interface
options = { options = {
services = {
disnix = { services.disnix = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = "Whether to enable Disnix"; description = "Whether to enable Disnix";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let
cfg = config.services.disnix;
inherit (pkgs.lib) mkIf;
job = { config = mkIf cfg.enable {
name = "disnix";
job = '' environment.systemPackages = [ pkgs.disnix ];
description "Disnix server"
start on dbus services.dbus.enable = true;
stop on shutdown services.dbus.packages = [ pkgs.disnix ];
script jobAttrs.disnix =
{ description = "Disnix server";
startOn = "dbus";
stopOn = "shutdown";
script =
''
export ACTIVATION_SCRIPTS=${pkgs.disnix_activation_scripts}/libexec/disnix/activation-scripts export ACTIVATION_SCRIPTS=${pkgs.disnix_activation_scripts}/libexec/disnix/activation-scripts
export PATH=${pkgs.nixUnstable}/bin export PATH=${pkgs.nixUnstable}/bin
export HOME=/root export HOME=/root
${pkgs.disnix}/bin/disnix-service ${pkgs.disnix}/bin/disnix-service
end script
''; '';
}; };
in
mkIf cfg.enable {
require = [
#../upstart-jobs/default.nix
#../upstart-jobs/dbus.nix # services.dbus.*
options
];
environment.systemPackages = [ pkgs.disnix ];
services = {
extraJobs = [job];
dbus = {
enable = true;
packages = [ pkgs.disnix ];
};
}; };
} }

View File

@ -1,15 +1,22 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
uid = config.ids.uids.gpsd; uid = config.ids.uids.gpsd;
gid = config.ids.gids.gpsd; gid = config.ids.gids.gpsd;
cfg = config.services.gpsd;
in
{
###### interface
options = { options = {
services = {
gpsd = { services.gpsd = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -58,51 +65,41 @@ let
}; };
}; };
};
}; };
in
###### implementation ###### implementation
mkIf config.services.gpsd.enable {
require = [
options
];
users = { config = mkIf cfg.enable {
extraUsers = [
users.extraUsers = singleton
{ name = "gpsd"; { name = "gpsd";
inherit uid; inherit uid;
description = "gpsd daemon user"; description = "gpsd daemon user";
home = "/var/empty"; home = "/var/empty";
}
];
extraGroups = [
{ name = "gpsd";
inherit gid;
}
];
}; };
services = users.extraGroups = singleton
let cfg = config.services.gpsd; in { { name = "gpsd";
extraJobs = [{ inherit gid;
name = "gpsd"; };
job = jobAttrs.gpsd =
let gpsd = pkgs.gpsd; { description = "GPSD daemon";
in ''
description "GPSD daemon"
start on network-interfaces/started startOn = "network-interfaces/started";
stop on network-interfaces/stop stopOn = "network-interfaces/stop";
respawn ${gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \ exec =
''
respawn ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}" \
-S "${toString cfg.port}" \ -S "${toString cfg.port}" \
${if cfg.readonly then "-b" else ""} \ ${if cfg.readonly then "-b" else ""} \
"${cfg.device}" "${cfg.device}"
''; '';
}];
}; };
};
} }

View File

@ -3,12 +3,12 @@
# of the virtual consoles. The latter is useful for the installation # of the virtual consoles. The latter is useful for the installation
# CD. # CD.
{pkgs, config, options, ...}: { config, pkgs, options, ... }:
with pkgs.lib;
let let
inherit (pkgs.lib) mkOption mkIf types;
cfg = config.services.nixosManual; cfg = config.services.nixosManual;
manual = import ../../../doc/manual { manual = import ../../../doc/manual {
@ -72,18 +72,22 @@ in
boot.extraTTYs = mkIf cfg.showManual [cfg.ttyNumber]; boot.extraTTYs = mkIf cfg.showManual [cfg.ttyNumber];
services.extraJobs = mkIf cfg.showManual (pkgs.lib.singleton jobAttrs = mkIf cfg.showManual
{ nixosManual =
{ name = "nixos-manual"; { name = "nixos-manual";
job = '' description = "NixOS manual";
description "NixOS manual"
start on udev startOn = "udev";
stop on shutdown stopOn = "shutdown";
respawn ${cfg.browser} ${manual}/share/doc/nixos/manual.html \
exec =
''
${cfg.browser} ${manual}/share/doc/nixos/manual.html \
< /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1 < /dev/tty${toString cfg.ttyNumber} > /dev/tty${toString cfg.ttyNumber} 2>&1
''; '';
}); };
};
services.ttyBackgrounds.specificThemes = mkIf cfg.showManual services.ttyBackgrounds.specificThemes = mkIf cfg.showManual
[ { tty = cfg.ttyNumber; [ { tty = cfg.ttyNumber;

View File

@ -1,13 +1,22 @@
{ config, pkgs, ... }:
{pkgs, config, ...}: with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption mkIf;
cfgC = config.services.synergy.client;
cfgS = config.services.synergy.server;
in
{
###### interface
options = { options = {
services = {
synergy = { services.synergy = {
# !!! All these option descriptions needs to be cleaned up.
client = { client = {
enable = mkOption { enable = mkOption {
@ -51,56 +60,49 @@ let
}; };
}; };
}; };
}; };
};
###### implementation ###### implementation
inherit (pkgs.lib) optional; config = {
cfgC = (config.services.synergy.client); jobAttrs =
cfgS = (config.services.synergy.server);
clientJob = { optionalAttrs cfgC.enable
name = "synergy-client"; { synergyClient =
{ name = "synergy-client";
job = '' description = "Synergy client";
description "synergy client"
start on started network-interfaces startOn = "network-interfaces/started";
stop on stopping network-interfaces stopOn = "network-interfaces/stopped";
respawn ${pkgs.synergy}/bin/synergyc ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" } exec = "${pkgs.synergy}/bin/synergyc ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" }";
'';
}; };
}
serverJob = { // optionalAttrs cfgS.enable
name = "synergy-server"; { synergyServer =
{ name = "synergy-server";
job = '' description = "Synergy server";
description "synergy server"
start on started network-interfaces startOn = "network-interfaces/started";
stop on stopping network-interfaces stopOn = "network-interfaces/stopped";
exec =
''
respawn ${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} \ respawn ${pkgs.synergy}/bin/synergys -c ${cfgS.configFile} \
-f ${if cfgS.address == "" then "" else "-a ${cfgS.address}"} \ -f ${if cfgS.address == "" then "" else "-a ${cfgS.address}"} \
${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" } ${if cfgS.screenName == "" then "" else "-n ${cfgS.screenName}" }
''; '';
}; };
in
{
require = [
options
];
services = {
extraJobs = (optional cfgS.enable serverJob)
++ (optional cfgC.enable clientJob);
}; };
};
} }
/* SYNERGY SERVER example configuration file /* SYNERGY SERVER example configuration file

View File

@ -1,13 +1,95 @@
# Nagios system/network monitoring daemon. # Nagios system/network monitoring daemon.
{ config, pkgs, ... }: { config, pkgs, ... }:
###### interface with pkgs.lib;
let let
inherit (pkgs.lib) mkOption;
cfg = config.services.nagios;
nagiosUser = "nagios";
nagiosGroup = "nogroup";
nagiosState = "/var/lib/nagios";
nagiosLogDir = "/var/log/nagios";
nagiosObjectDefs =
[ ./timeperiods.cfg
./host-templates.cfg
./service-templates.cfg
./commands.cfg
] ++ cfg.objectDefs;
nagiosObjectDefsDir = pkgs.runCommand "nagios-objects" {inherit nagiosObjectDefs;}
"ensureDir $out; ln -s $nagiosObjectDefs $out/";
nagiosCfgFile = pkgs.writeText "nagios.cfg"
''
# Paths for state and logs.
log_file=${nagiosLogDir}/current
log_archive_path=${nagiosLogDir}/archive
status_file=${nagiosState}/status.dat
object_cache_file=${nagiosState}/objects.cache
comment_file=${nagiosState}/comment.dat
downtime_file=${nagiosState}/downtime.dat
temp_file=${nagiosState}/nagios.tmp
lock_file=/var/run/nagios.lock # Not used I think.
state_retention_file=${nagiosState}/retention.dat
# Configuration files.
#resource_file=resource.cfg
cfg_dir=${nagiosObjectDefsDir}
# Uid/gid that the daemon runs under.
nagios_user=${nagiosUser}
nagios_group=${nagiosGroup}
# Misc. options.
illegal_macro_output_chars=`~$&|'"<>
retain_state_information=1
''; # "
# Plain configuration for the Nagios web-interface with no
# authentication.
nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf"
''
main_config_file=${nagiosCfgFile}
use_authentication=0
url_html_path=/nagios
'';
urlPath = cfg.urlPath;
extraHttpdConfig =
''
ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin
<Directory "${pkgs.nagios}/sbin">
Options ExecCGI
AllowOverride None
Order allow,deny
Allow from all
SetEnv NAGIOS_CGI_CONFIG ${nagiosCGICfgFile}
</Directory>
Alias ${urlPath} ${pkgs.nagios}/share
<Directory "${pkgs.nagios}/share">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>
'';
in
{
###### interface
options = { options = {
services = {
nagios = { services.nagios = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -52,161 +134,63 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let
cfg = config.services.nagios;
inherit (pkgs.lib) mkIf mkThenElse;
nagiosUser = "nagios"; config = mkIf cfg.enable {
nagiosGroup = "nogroup";
nagiosState = "/var/lib/nagios"; users.extraUsers = singleton
nagiosLogDir = "/var/log/nagios"; { name = nagiosUser;
nagiosObjectDefs = [
./timeperiods.cfg
./host-templates.cfg
./service-templates.cfg
./commands.cfg
] ++ cfg.objectDefs;
nagiosObjectDefsDir = pkgs.runCommand "nagios-objects" {inherit nagiosObjectDefs;}
"ensureDir $out; ln -s $nagiosObjectDefs $out/";
nagiosCfgFile = pkgs.writeText "nagios.cfg" "
# Paths for state and logs.
log_file=${nagiosLogDir}/current
log_archive_path=${nagiosLogDir}/archive
status_file=${nagiosState}/status.dat
object_cache_file=${nagiosState}/objects.cache
comment_file=${nagiosState}/comment.dat
downtime_file=${nagiosState}/downtime.dat
temp_file=${nagiosState}/nagios.tmp
lock_file=/var/run/nagios.lock # Not used I think.
state_retention_file=${nagiosState}/retention.dat
# Configuration files.
#resource_file=resource.cfg
cfg_dir=${nagiosObjectDefsDir}
# Uid/gid that the daemon runs under.
nagios_user=${nagiosUser}
nagios_group=${nagiosGroup}
# Misc. options.
illegal_macro_output_chars=`~$&|'\"<>
retain_state_information=1
";
# Plain configuration for the Nagios web-interface with no
# authentication.
nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf" "
main_config_file=${nagiosCfgFile}
use_authentication=0
url_html_path=/nagios
";
urlPath = cfg.urlPath;
extraHttpdConfig = "
ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin
<Directory \"${pkgs.nagios}/sbin\">
Options ExecCGI
AllowOverride None
Order allow,deny
Allow from all
SetEnv NAGIOS_CGI_CONFIG ${nagiosCGICfgFile}
</Directory>
Alias ${urlPath} ${pkgs.nagios}/share
<Directory \"${pkgs.nagios}/share\">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>
";
user = {
name = nagiosUser;
uid = config.ids.uids.nagios; uid = config.ids.uids.nagios;
description = "Nagios monitoring daemon"; description = "Nagios monitoring daemon";
home = nagiosState; home = nagiosState;
}; };
job = { # This isn't needed, it's just so that the user can type "nagiostats
name = "nagios"; # -c /etc/nagios.cfg".
environment.etc = singleton
{ source = nagiosCfgFile;
target = "nagios.cfg";
};
# Run `nagios -v' to check the validity of the configuration file so environment.systemPackages = [ pkgs.nagios ];
jobAttrs.nagios =
{ # Run `nagios -v' to check the validity of the configuration file so
# that a nixos-rebuild fails *before* we kill the running Nagios # that a nixos-rebuild fails *before* we kill the running Nagios
# daemon. # daemon.
buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}"; buildHook = "${pkgs.nagios}/bin/nagios -v ${nagiosCfgFile}";
job = " description = "Nagios monitoring daemon";
description \"Nagios monitoring daemon\"
start on network-interfaces/started startOn = "network-interfaces/started";
stop on network-interfaces/stop stopOn = "network-interfaces/stop";
start script preStart =
''
mkdir -m 0755 -p ${nagiosState} ${nagiosLogDir} mkdir -m 0755 -p ${nagiosState} ${nagiosLogDir}
chown ${nagiosUser} ${nagiosState} ${nagiosLogDir} chown ${nagiosUser} ${nagiosState} ${nagiosLogDir}
end script '';
respawn script =
''
script
for i in ${toString config.services.nagios.plugins}; do for i in ${toString config.services.nagios.plugins}; do
export PATH=$i/bin:$i/sbin:$i/libexec:$PATH export PATH=$i/bin:$i/sbin:$i/libexec:$PATH
done done
exec ${pkgs.nagios}/bin/nagios ${nagiosCfgFile} exec ${pkgs.nagios}/bin/nagios ${nagiosCfgFile}
end script '';
";
};
in
mkIf cfg.enable {
require = [
# ../../upstart-jobs/default.nix # config.services.extraJobs
# ../../system/user.nix # users = { .. }
# ? # config.environment.etc
# ? # config.environment.extraPackages
# ../../upstart-jobs/httpd.nix # config.services.httpd
options
];
environment = {
# This isn't needed, it's just so that the user can type "nagiostats
# -c /etc/nagios.cfg".
etc = [
{ source = nagiosCfgFile;
target = "nagios.cfg";
}
];
systemPackages = [pkgs.nagios];
}; };
users = { services.httpd = mkIf cfg.enableWebInterface {
extraUsers = [user];
};
services = {
extraJobs = [job];
httpd = mkIf cfg.enableWebInterface {
extraConfig = mkThenElse { extraConfig = mkThenElse {
thenPart = extraHttpdConfig; thenPart = extraHttpdConfig;
elsePart = ""; elsePart = "";
}; };
}; };
}; };
} }

View File

@ -1,35 +1,8 @@
# Zabbix agent daemon. # Zabbix agent daemon.
{ config, pkgs, ... }: { config, pkgs, ... }:
###### interface with pkgs.lib;
let
inherit (pkgs.lib) mkOption;
options = {
services = {
zabbixAgent = {
enable = mkOption {
default = false;
description = "
Whether to run the Zabbix monitoring agent on this machine.
It will send monitoring data to a Zabbix server.
";
};
server = mkOption {
default = "127.0.0.1";
description = ''
The IP address or hostname of the Zabbix server to connect to.
'';
};
};
};
};
in
###### implementation
let let
cfg = config.services.zabbixAgent; cfg = config.services.zabbixAgent;
@ -40,7 +13,8 @@ let
pidFile = "${stateDir}/zabbix_agentd.pid"; pidFile = "${stateDir}/zabbix_agentd.pid";
configFile = pkgs.writeText "zabbix_agentd.conf" '' configFile = pkgs.writeText "zabbix_agentd.conf"
''
Server = ${cfg.server} Server = ${cfg.server}
LogFile = ${logDir}/zabbix_agentd LogFile = ${logDir}/zabbix_agentd
@ -50,32 +24,65 @@ let
StartAgents = 5 StartAgents = 5
''; '';
user = { in
name = "zabbix";
{
###### interface
options = {
services.zabbixAgent = {
enable = mkOption {
default = false;
description = ''
Whether to run the Zabbix monitoring agent on this machine.
It will send monitoring data to a Zabbix server.
'';
};
server = mkOption {
default = "127.0.0.1";
description = ''
The IP address or hostname of the Zabbix server to connect to.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
users.extraUsers = singleton
{ name = "zabbix";
uid = config.ids.uids.zabbix; uid = config.ids.uids.zabbix;
description = "Zabbix daemon user"; description = "Zabbix daemon user";
}; };
job = { jobAttrs.zabbix_agent =
name = "zabbix-agent"; { #name = "zabbix-agent"; !!! mkIf bug
job = '' description = "Zabbix agent daemon";
start on network-interfaces/started
stop on network-interfaces/stop
description "Zabbix agent daemon" startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
start script preStart =
''
mkdir -m 0755 -p ${stateDir} ${logDir} mkdir -m 0755 -p ${stateDir} ${logDir}
chown zabbix ${stateDir} ${logDir} chown zabbix ${stateDir} ${logDir}
export PATH=${pkgs.nettools}/bin:$PATH export PATH=${pkgs.nettools}/bin:$PATH
${pkgs.zabbixAgent}/sbin/zabbix_agentd --config ${configFile} ${pkgs.zabbixAgent}/sbin/zabbix_agentd --config ${configFile}
end script '';
respawn sleep 100000 postStop =
''
stop script
# !!! this seems to leave processes behind. # !!! this seems to leave processes behind.
#pid=$(cat ${pidFile}) #pid=$(cat ${pidFile})
#if test -n "$pid"; then #if test -n "$pid"; then
@ -84,25 +91,9 @@ let
# So instead kill the agent in a brutal fashion. # So instead kill the agent in a brutal fashion.
while ${pkgs.procps}/bin/pkill -u zabbix zabbix_agentd; do true; done while ${pkgs.procps}/bin/pkill -u zabbix zabbix_agentd; do true; done
end script
''; '';
}; };
ifEnable = pkgs.lib.ifEnable cfg.enable;
in
{
require = [
# ../upstart-jobs/default.nix
# ../system/user.nix # users = { .. }
options
];
services = {
extraJobs = ifEnable [job];
}; };
users = {
extraUsers = ifEnable [user];
};
} }

View File

@ -1,25 +1,8 @@
# Zabbix server daemon. # Zabbix server daemon.
{ config, pkgs, ... }: { config, pkgs, ... }:
###### interface with pkgs.lib;
let
inherit (pkgs.lib) mkOption;
options = {
services = {
zabbixServer = {
enable = mkOption {
default = false;
description = "
Whether to run the Zabbix server on this machine.
";
};
};
};
};
in
###### implementation
let let
stateDir = "/var/run/zabbix"; stateDir = "/var/run/zabbix";
@ -30,7 +13,8 @@ let
pidFile = "${stateDir}/zabbix_server.pid"; pidFile = "${stateDir}/zabbix_server.pid";
configFile = pkgs.writeText "zabbix_server.conf" '' configFile = pkgs.writeText "zabbix_server.conf"
''
LogFile = ${logDir}/zabbix_server LogFile = ${logDir}/zabbix_server
PidFile = ${pidFile} PidFile = ${pidFile}
@ -40,22 +24,43 @@ let
DBUser = zabbix DBUser = zabbix
''; '';
user = { in
name = "zabbix";
{
###### interface
options = {
services.zabbixServer.enable = mkOption {
default = false;
description = ''
Whether to run the Zabbix server on this machine.
'';
};
};
###### implementation
config = mkIf config.services.zabbixServer.enable {
users.extraUsers = singleton
{ name = "zabbix";
uid = config.ids.uids.zabbix; uid = config.ids.uids.zabbix;
description = "Zabbix daemon user"; description = "Zabbix daemon user";
}; };
job = { jobAttrs.zabbix_server =
name = "zabbix-server"; { #name = "zabbix-server"; !!! mkIf bug
job = '' description = "Zabbix server daemon";
description "Zabbix server daemon"
start on postgresql/started startOn = "postgresql";
stop on shutdown stopOn = "shutdown";
start script preStart =
''
mkdir -m 0755 -p ${stateDir} ${logDir} ${libDir} mkdir -m 0755 -p ${stateDir} ${logDir} ${libDir}
chown zabbix ${stateDir} ${logDir} ${libDir} chown zabbix ${stateDir} ${logDir} ${libDir}
@ -70,32 +75,14 @@ let
export PATH=${pkgs.nettools}/bin:$PATH export PATH=${pkgs.nettools}/bin:$PATH
${pkgs.zabbixServer}/sbin/zabbix_server --config ${configFile} ${pkgs.zabbixServer}/sbin/zabbix_server --config ${configFile}
end script
respawn sleep 100000
stop script
while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done
end script
''; '';
postStop =
''
while ${pkgs.procps}/bin/pkill -u zabbix zabbix_server; do true; done
'';
}; };
ifEnable = pkgs.lib.ifEnable config.services.zabbixServer.enable;
in
{
require = [
# ../upstart-jobs/default.nix
# ../system/user.nix # users = { .. }
options
];
services = {
extraJobs = ifEnable [job];
}; };
users = {
extraUsers = ifEnable [user];
};
} }

View File

@ -1,97 +1,96 @@
{ config, pkgs, ... }:
{pkgs, config, ...}: with pkgs.lib;
let
inherit (pkgs) writeText openssh;
cfg = config.services.nfsKernel;
exports =
if builtins.pathExists cfg.exports
then cfg.exports
else pkgs.writeText "exports" cfg.exports;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
nfsKernel = { services.nfsKernel = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = ''
wether to use the kernel nfs functionality to export filesystems. Whether to enable the kernel's NFS server.
You should be aware about existing security issues. '';
requires portmap!
";
}; };
# !!! Why is this a file? Why not a list of export entries?
exports = mkOption { exports = mkOption {
check = v: v != "/etc/exports"; # this won't work check = v: v != "/etc/exports"; # this won't work
description = " description = ''
the file listing the directories to be exported. The file listing the directories to be exported. See
install nfsUtils and run man exports to learn about its format. <citerefentry><refentrytitle>exports</refentrytitle>
The exports setting can either be a file path or the file contents. <manvolnum>5</manvolnum></citerefentry> for the format.
Don't use /etc/exports. This won't work as nix will overwrite it. '';
";
}; };
hostName = mkOption { hostName = mkOption {
default = null; default = null;
description = " description = ''
specify a particular hostname (or address) that NFS requests will be accepted on. Hostname or address on which NFS requests will be accepted.
Default: all. Default is all. See the <option>-H</option> option in
See man rpc.nfsd (-H option) <citerefentry><refentrytitle>nfsd</refentrytitle>
"; <manvolnum>8</manvolnum></citerefentry>.
'';
}; };
nproc = mkOption { nproc = mkOption {
default = 8; default = 8;
description = " description = ''
specify the number of NFS server threads. (-> man rpc.nfsd). Defaults to recommended value 8 Number of NFS server threads. Defaults to the recommended value of 8.
"; '';
}; };
createMountPoints = mkOption { createMountPoints = mkOption {
default = false; default = false;
description = "Whether to create the mount points in the exports file at startup time."; description = "Whether to create the mount points in the exports file at startup time.";
}; };
}; };
}; };
};
###### implementation ###### implementation
inherit (pkgs) writeText openssh; config = mkIf config.services.nfsKernel.enable {
cfg = (config.services.nfsKernel); environment.etc = singleton
modprobe = config.system.sbin.modprobe;
exports = if builtins.pathExists cfg.exports
then cfg.exports else pkgs.writeText "exports" cfg.exports;
in
mkIf config.services.nfsKernel.enable {
require = [
options
];
environment.etc = [
{ source = exports; { source = exports;
target = "exports"; } target = "exports";
]; };
services = { jobAttrs.nfs_kernel_exports =
extraJobs = [ { name = "nfs-kernel-exports";
{
name = "nfs-kernel-exports";
job = '' description = "Kernel NFS server";
description "export filesystems using kernel nfs"
start on network-interfaces/started startOn = "network-interfaces/started";
stop on network-interfaces/stop stopOn = "network-interfaces/stop";
start script preStart =
''
export PATH=${pkgs.nfsUtils}/sbin:$PATH export PATH=${pkgs.nfsUtils}/sbin:$PATH
mkdir -p /var/lib/nfs mkdir -p /var/lib/nfs
${modprobe}/sbin/modprobe nfsd || true ${config.system.sbin.modprobe}/sbin/modprobe nfsd || true
${if cfg.createMountPoints == true then ${optionalString cfg.createMountPoints
'' ''
# create export directories: # create export directories:
# skip comments, take first col which may either be a quoted # skip comments, take first col which may either be a quoted
@ -99,56 +98,52 @@ mkIf config.services.nfsKernel.enable {
sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \ sed '/^#.*/d;s/^"\([^"]*\)".*/\1/;t;s/[ ].*//' ${exports} \
| xargs -d '\n' mkdir -p | xargs -d '\n' mkdir -p
'' ''
else ""} }
# exports file is ${exports} # exports file is ${exports}
# keep this comment so that this job is restarted whenever exports changes! # keep this comment so that this job is restarted whenever exports changes!
exportfs -ra exportfs -ra
end script
respawn sleep 1000000
''; '';
}
{
name = "nfs-kernel-rpc-nfsd";
job = ''
description "export filesystems using kernel nfs"
start on nfs-kernel-exports/started
stop on nfs-kernel-exports/stop
respawn ${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} ${builtins.toString cfg.nproc}
'';
}
{
name = "nfs-kernel-mountd";
job = ''
description "export filesystems using kernel nfs"
start on nfs-kernel-rpc-nfsd/started
stop on nfs-kernel-exports/stop
respawn ${pkgs.nfsUtils}/sbin/rpc.mountd -F -f ${exports}
'';
}
{
name = "nfs-kernel-statd";
job = ''
description "NSM (Network Status Monitor) of the RPC protocol"
start on nfs-kernel-rpc-nfsd/started
stop on nfs-kernel-exports/stop
start script
mkdir -p /var/lib/nfs
end script
respawn ${pkgs.nfsUtils}/sbin/rpc.statd -F
'';
}
];
}; };
jobAttrs.nfs_kernel_nfsd =
{ name = "nfs-kernel-nfsd";
description = "Kernel NFS server";
startOn = "nfs-kernel-exports/started";
stopOn = "nfs-kernel-exports/stop";
exec = "${pkgs.nfsUtils}/sbin/rpc.nfsd ${if cfg.hostName != null then "-H ${cfg.hostName}" else ""} ${builtins.toString cfg.nproc}";
};
jobAttrs.nfs_kernel_mountd =
{ name = "nfs-kernel-mountd";
description = "Kernel NFS server - mount daemon";
startOn = "nfs-kernel-nfsd/started";
stopOn = "nfs-kernel-exports/stop";
exec = "${pkgs.nfsUtils}/sbin/rpc.mountd -F -f ${exports}";
};
jobAttrs.nfs_kernel_statd =
{ name = "nfs-kernel-statd";
description = "Kernel NFS server - Network Status Monitor";
startOn = "nfs-kernel-nfsd/started";
stopOn = "nfs-kernel-exports/stop";
preStart =
''
mkdir -p /var/lib/nfs
'';
exec = "${pkgs.nfsUtils}/sbin/rpc.statd -F";
};
};
} }

View File

@ -1,12 +1,78 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.samba;
user = "smbguest";
group = "smbguest";
logDir = "/var/log/samba";
privateDir = "/var/samba/private";
inherit (pkgs) samba;
setupScript =
''
mkdir -p /var/lock
if ! test -d /home/smbd ; then
mkdir -p /home/smbd
chown ${user} /home/smbd
chmod a+rwx /home/smbd
fi
if ! test -d /var/samba ; then
mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd
fi
passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' /nix/store/nnmrqalldfv2vkwy6qpg340rv7w34lmp-smb.conf)"
if [ -n "$passwdFile" ]; then
echo 'INFO: creating directory containing passwd file'
mkdir -p "$(dirname "$passwdFile")"
fi
mkdir -p ${logDir}
mkdir -p ${privateDir}
# The following line is to trigger a restart of the daemons when
# the configuration changes:
# ${configFile}
'';
configFile = pkgs.writeText "smb.conf"
''
[ global ]
log file = ${logDir}/log.%m
private dir = ${privateDir}
${optionalString cfg.syncPasswordsByPam "pam password change = true"}
${cfg.extraConfig}
'';
daemonJob = appName: args:
{ name = "samba-${appName}";
description = "Samba Service daemon ${appName}";
startOn = "samba/started";
stopOn = "samba-control/stop";
exec = "${samba}/sbin/${appName} ${args}";
};
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf mkAlways;
options = { options = {
services = {
samba = { # !!! clean up the descriptions.
services.samba = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -29,6 +95,7 @@ let
}; };
extraConfig = mkOption { extraConfig = mkOption {
# !!! Bad default.
default = '' default = ''
# [global] continuing global section here, section is started by nix to set pids etc # [global] continuing global section here, section is started by nix to set pids etc
@ -57,44 +124,6 @@ let
invalid users = root invalid users = root
passdb backend = tdbsam passdb backend = tdbsam
passwd program = /usr/bin/passwd %u passwd program = /usr/bin/passwd %u
### end [ global ] section
# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home directory as \\server\username
;[homes]
; comment = Home Directories
; browseable = no
; writable = no
# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
; create mask = 0700
# this directory and user is created automatically for you by nixos
;[default]
; path = /home/smbd
; read only = no
; guest ok = yes
# this directory and user is created automatically for you by nixos
;[default]
; path = /home/smbd
; read only = no
; guest ok = yes
# additional share example
;[raidbackup]
; path = /home/raidbackup/files
; read only = no
; guest ok = no
; available = yes
; browseable = yes
; public = yes
; valid users = raidbackup
; comment = Raid backup Files
''; '';
description = " description = "
@ -108,128 +137,51 @@ let
"; ";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.samba.enable {
cfg = config.services.samba; users.extraUsers = singleton
user = "smbguest";
group = "smbguest";
logDir = "/var/log/samba";
privateDir = "/var/samba/private";
inherit (pkgs) samba;
setupScript = ''
mkdir -p /var/lock
if ! test -d /home/smbd ; then
mkdir -p /home/smbd
chown ${user} /home/smbd
chmod a+rwx /home/smbd
fi
if ! test -d /var/samba ; then
mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd
fi
passwdFile="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' /nix/store/nnmrqalldfv2vkwy6qpg340rv7w34lmp-smb.conf)"
if [ -n "$passwdFile" ]; then
echo 'INFO: creating directory containing passwd file'
mkdir -p "$(dirname "$passwdFile")"
fi
mkdir -p ${logDir}
mkdir -p ${privateDir}
'';
configFile = pkgs.writeText "smb.conf" ''
[ global ]
log file = ${logDir}/log.%m
private dir = ${privateDir}
${if cfg.syncPasswordsByPam then "pam password change = true" else "" /* does this make sense ? */ }
${cfg.extraConfig}";
'';
daemonJob = appName : args :
{
name = "samba-${appName}";
job = ''
description "Samba Service daemon ${appName}"
start on samba-control/started
stop on samba-control/stop
respawn ${samba}/sbin/${appName} ${args}
'';
};
in
mkIf config.services.samba.enable {
require = [
options
];
users = {
extraUsers = [
{ name = user; { name = user;
description = "Samba service user"; description = "Samba service user";
group = group; group = group;
} };
];
extraGroups = [ users.extraGroups = singleton
{ name = group; { name = group;
}
];
}; };
# always provide a smb.conf to shut up programs like smbclient and smbspool. # always provide a smb.conf to shut up programs like smbclient and smbspool.
environment = { environment.etc = mkAlways (singleton
etc = mkAlways [{ { source =
source = if cfg.enable then configFile else pkgs.writeText "smb-dummy.conf" "# samba is disabled. Purpose see samba expression in nixpkgs"; if cfg.enable then configFile
else pkgs.writeText "smb-dummy.conf" "# Samba is disabled.";
target = "samba/smb.conf"; target = "samba/smb.conf";
}]; });
# Dummy job to start the real Samba daemons (nmbd, smbd, winbindd).
jobAttrs.sambaControl =
{ name = "samba";
description = "Samba server";
startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
preStart = setupScript;
}; };
services = { # nmbd says "standard input is not a socket, assuming -D option",
# but using -i makes it stay in foreground (?)
jobAttrs.nmbd = daemonJob "nmbd" " -i -F";
extraJobs = [ jobAttrs.smbd = daemonJob "smbd" " -i -F";
{ name = "samba-control"; # start this dummy job to start the real samba daemons nmbd, smbd, winbindd
job = ''
description "samba job starting/stopping the real samba jobs";
start on network-interfaces/started jobAttrs.winbindd = daemonJob "winbindd" " -F";
stop on network-interfaces/stop
start script
${setupScript}
end script
respawn sleep 1000000 # !!! hack
# put the store path here so that daemons are restarted when configuration changes
# config is ${configFile}
'';
}
# add -S to get debugging output on stdout
# config directory is passed by configure at compilation time
( daemonJob "nmbd" " -i -F" ) # nmbd says "standard input is not a socket, assuming -D option", but using -i makes it stay in foreground (?)
( daemonJob "smbd" " -i -F" ) # dito
( daemonJob "winbindd" " -F" )
];
}; };
} }

View File

@ -1,13 +1,37 @@
# Avahi daemon. # Avahi daemon.
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.avahi;
inherit (pkgs) avahi;
avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" ''
[server]
host-name=${hostName}
browse-domains=${concatStringsSep ", " browseDomains}
use-ipv4=${if ipv4 then "yes" else "no"}
use-ipv6=${if ipv6 then "yes" else "no"}
[wide-area]
enable-wide-area=${if wideArea then "yes" else "no"}
[publish]
disable-publishing=${if publishing then "no" else "yes"}
'';
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption;
options = { options = {
services = {
avahi = { services.avahi = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -65,52 +89,40 @@ let
sourced, it will set up an appropriate `LD_LIBRARY_PATH', though. sourced, it will set up an appropriate `LD_LIBRARY_PATH', though.
''; '';
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let
cfg = config.services.avahi;
inherit (pkgs.lib) mkIf mkThenElse;
inherit (pkgs) avahi writeText lib; config = mkIf cfg.enable {
avahiDaemonConf = with cfg; writeText "avahi-daemon.conf" '' users.extraUsers = singleton
[server] { name = "avahi";
host-name=${hostName}
browse-domains=${lib.concatStringsSep ", " browseDomains}
use-ipv4=${if ipv4 then "yes" else "no"}
use-ipv6=${if ipv6 then "yes" else "no"}
[wide-area]
enable-wide-area=${if wideArea then "yes" else "no"}
[publish]
disable-publishing=${if publishing then "no" else "yes"}
'';
user = {
name = "avahi";
uid = config.ids.uids.avahi; uid = config.ids.uids.avahi;
description = "`avahi-daemon' privilege separation user"; description = "`avahi-daemon' privilege separation user";
home = "/var/empty"; home = "/var/empty";
}; };
group = { users.extraGroups = singleton
name = "avahi"; { name = "avahi";
gid = config.ids.gids.avahi; gid = config.ids.gids.avahi;
}; };
job = { system.nssModules = optional cfg.nssmdns pkgs.nssmdns;
name = "avahi-daemon";
job = '' environment.systemPackages = [ avahi ];
start on network-interfaces/started
stop on network-interfaces/stop jobAttrs.avahi_daemon =
respawn { name = "avahi-daemon";
script
startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
script =
''
export PATH="${avahi}/bin:${avahi}/sbin:$PATH" export PATH="${avahi}/bin:${avahi}/sbin:$PATH"
# Make NSS modules visible so that `avahi_nss_support ()' can # Make NSS modules visible so that `avahi_nss_support ()' can
@ -118,42 +130,12 @@ let
export LD_LIBRARY_PATH="${config.system.nssModules.path}" export LD_LIBRARY_PATH="${config.system.nssModules.path}"
exec ${avahi}/sbin/avahi-daemon --daemonize -f "${avahiDaemonConf}" exec ${avahi}/sbin/avahi-daemon --daemonize -f "${avahiDaemonConf}"
end script
''; '';
}; };
in
mkIf cfg.enable { services.dbus.enable = true;
require = [ services.dbus.packages = [avahi];
# ../upstart-jobs/default.nix # config.services.extraJobs
# ../system/? # system.nssModules
# ? # config.environment.etc
# ../system/user.nix # users.*
# ../upstart-jobs/udev.nix # services.udev.*
# ../upstart-jobs/dbus.nix # services.dbus.*
# ? # config.environment.extraPackages
options
];
system = {
nssModules = pkgs.lib.optional cfg.nssmdns pkgs.nssmdns;
}; };
environment = {
systemPackages = [avahi];
};
users = {
extraUsers = [user];
extraGroups = [group];
};
services = {
extraJobs = [job];
dbus = {
enable = true;
packages = [avahi];
};
};
} }

View File

@ -1,30 +1,85 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces";
cfg = config.services.bind;
confFile = pkgs.writeText "named.conf"
''
acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} };
acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} };
options {
listen-on {any;};
listen-on-v6 {any;};
allow-query { cachenetworks; };
blackhole { badnetworks; };
forward first;
forwarders { ${concatMapStrings (entry: " ${entry}; ") config.networking.nameservers} };
directory "/var/run/named";
pid-file "/var/run/named/named.pid";
};
${ concatMapStrings
({ name, file, master ? true, slaves ? [], masters ? [] }:
''
zone "${name}" {
type ${if master then "master" else "slave"};
file "${file}";
${ if master then
''
allow-transfer {
${concatMapStrings (ip: "${ip};\n") slaves}
};
''
else
''
masters {
${concatMapStrings (ip: "${ip};\n") masters}
};
''
}
allow-query { any; };
};
'')
cfg.zones }
'';
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
bind = { services.bind = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "
Whether to enable BIND domain name server. Whether to enable BIND domain name server.
"; ";
}; };
cacheNetworks = mkOption { cacheNetworks = mkOption {
default = ["127.0.0.0/24"]; default = ["127.0.0.0/24"];
description = " description = "
What networks are allowed to use us as a resolver. What networks are allowed to use us as a resolver.
"; ";
}; };
blockedNetworks = mkOption { blockedNetworks = mkOption {
default = []; default = [];
description = " description = "
What networks are just blocked. What networks are just blocked.
"; ";
}; };
zones = mkOption { zones = mkOption {
default = []; default = [];
description = " description = "
@ -40,84 +95,27 @@ let
slaves = []; slaves = [];
}]; }];
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.bind.enable {
startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces";
cfg = config.services.bind;
concatMapStrings = pkgs.lib.concatMapStrings;
namedConf = jobAttrs.bind =
('' { description = "BIND name server job";
acl cachenetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.cacheNetworks} };
acl badnetworks { ${concatMapStrings (entry: " ${entry}; ") cfg.blockedNetworks} };
options { preStart =
listen-on {any;};
listen-on-v6 {any;};
allow-query { cachenetworks; };
blackhole { badnetworks; };
forward first;
forwarders { ${concatMapStrings (entry: " ${entry}; ") config.networking.nameservers} };
directory "/var/run/named";
pid-file "/var/run/named/named.pid";
};
'')
+
(concatMapStrings
(_entry:let entry={master=true;slaves=[];masters=[];}//_entry; in
'' ''
zone "${entry.name}" {
type ${if entry.master then "master" else "slave"};
file "${entry.file}";
${ if entry.master then
''
allow-transfer {
${concatMapStrings (ip: ip+";\n") entry.slaves}
};
''
else
''
masters {
${concatMapStrings (ip: ip+";\n") entry.masters}
};
''
}
allow-query { any; };
};
''
)
cfg.zones
)
;
confFile = pkgs.writeText "named.conf" namedConf;
in
mkIf config.services.bind.enable {
require = [
options
];
services = {
extraJobs = [{
name = "bind";
job = ''
description "BIND name server job"
start script
${pkgs.coreutils}/bin/mkdir -p /var/run/named ${pkgs.coreutils}/bin/mkdir -p /var/run/named
end script
respawn ${pkgs.bind}/sbin/named -c ${confFile} -f
''; '';
}];
exec = "${pkgs.bind}/sbin/named -c ${confFile} -f";
}; };
};
} }

View File

@ -1,12 +1,22 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
bitlbeeUid = config.ids.uids.bitlbee;
inherit (config.services.bitlbee) portNumber interface;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
bitlbee = { services.bitlbee = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -34,58 +44,50 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.bitlbee.enable {
bitlbeeUid = config.ids.uids.bitlbee;
inherit (config.services.bitlbee) portNumber interface;
in
mkIf config.services.bitlbee.enable { users.extraUsers = singleton
require = options;
users = {
extraUsers = [
{ name = "bitlbee"; { name = "bitlbee";
uid = bitlbeeUid; uid = bitlbeeUid;
description = "BitlBee user"; description = "BitlBee user";
home = "/var/empty"; home = "/var/empty";
}
];
extraGroups = [
{ name = "bitlbee";
gid = config.ids.gids.bitlbee;
}
];
}; };
services.extraJobs = [{ users.extraGroups = singleton
name = "bitlbee"; { name = "bitlbee";
gid = config.ids.gids.bitlbee;
};
job = '' jobAttrs.bitlbee =
description "BitlBee IRC to other chat networks gateway" { description = "BitlBee IRC to other chat networks gateway";
start on network-interfaces/started startOn = "network-interfaces/started";
stop on network-interfaces/stop stopOn = "network-interfaces/stop";
start script preStart =
''
if ! test -d /var/lib/bitlbee if ! test -d /var/lib/bitlbee
then then
mkdir -p /var/lib/bitlbee mkdir -p /var/lib/bitlbee
chown bitlbee:bitlbee /var/lib/bitlbee chown bitlbee:bitlbee /var/lib/bitlbee
fi fi
end script '';
respawn ${pkgs.bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \ exec =
''
${pkgs.bitlbee}/sbin/bitlbee -F -p ${toString portNumber} \
-i ${interface} -u bitlbee -i ${interface} -u bitlbee
''; '';
}]; };
environment.systemPackages = [ pkgs.bitlbee ]; environment.systemPackages = [ pkgs.bitlbee ];
};
} }

View File

@ -1,12 +1,43 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.dhcpd;
stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant.
configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf"
''
default-lease-time 600;
max-lease-time 7200;
authoritative;
ddns-update-style ad-hoc;
log-facility local1; # see dhcpd.nix
${cfg.extraConfig}
${pkgs.lib.concatMapStrings
(machine: ''
host ${machine.hostName} {
hardware ethernet ${machine.ethernetAddress};
fixed-address ${machine.ipAddress};
}
'')
cfg.machines
}
'';
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
dhcpd = { services.dhcpd = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -69,55 +100,22 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.dhcpd.enable {
cfg = config.services.dhcpd; jobAttrs.dhcpd =
{ description = "DHCP server";
stateDir = "/var/lib/dhcp"; # Don't use /var/state/dhcp; not FHS-compliant. startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
machines = pkgs.lib.concatMapStrings (machine: ''
host ${machine.hostName} {
hardware ethernet ${machine.ethernetAddress};
fixed-address ${machine.ipAddress};
}
'') cfg.machines;
configFile = if cfg.configFile != null then cfg.configFile else pkgs.writeText "dhcpd.conf" ''
default-lease-time 600;
max-lease-time 7200;
authoritative;
ddns-update-style ad-hoc;
log-facility local1; # see dhcpd.nix
${cfg.extraConfig}
${machines}
'';
in
mkIf config.services.dhcpd.enable {
require = [
options
];
services = {
extraJobs = [{
name = "dhcpd";
job = ''
description "DHCP server"
start on network-interfaces/started
stop on network-interfaces/stop
script
script =
''
mkdir -m 755 -p ${stateDir} mkdir -m 755 -p ${stateDir}
touch ${stateDir}/dhcpd.leases touch ${stateDir}/dhcpd.leases
@ -125,9 +123,9 @@ mkIf config.services.dhcpd.enable {
exec ${pkgs.dhcp}/sbin/dhcpd -f -cf ${configFile} \ exec ${pkgs.dhcp}/sbin/dhcpd -f -cf ${configFile} \
-lf ${stateDir}/dhcpd.leases \ -lf ${stateDir}/dhcpd.leases \
${toString cfg.interfaces} ${toString cfg.interfaces}
end script
''; '';
}];
}; };
};
} }

View File

@ -1,12 +1,21 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.ejabberd;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
ejabberd = { services.ejabberd = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = "Whether to enable ejabberd server"; description = "Whether to enable ejabberd server";
@ -31,37 +40,24 @@ let
default = "\"localhost\""; default = "\"localhost\"";
description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas"; description = "Virtualhosts that ejabberd should host. Hostnames are surrounded with doublequotes and separated by commas";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf cfg.enable {
cfg = config.services.ejabberd; jobAttrs.ejabberd =
{ description = "EJabberd server";
in startOn = "network-interface/started";
stopOn = "network-interfaces/stop";
mkIf config.services.ejabberd.enable { preStart =
''
require = [
options
];
services = {
extraJobs = [{
name = "ejabberd";
job = ''
description "EJabberd server"
start on network-interface/started
stop on network-interfaces/stop
start script
# Initialise state data # Initialise state data
mkdir -p ${cfg.logsDir} mkdir -p ${cfg.logsDir}
@ -72,14 +68,16 @@ mkIf config.services.ejabberd.enable {
mkdir -p ${cfg.confDir} mkdir -p ${cfg.confDir}
test -f ${cfg.confDir}/ejabberd.cfg || sed -e 's|{hosts, \["localhost"\]}.|{hosts, \[${cfg.virtualHosts}\]}.|' ${pkgs.ejabberd}/etc/ejabberd/ejabberd.cfg > ${cfg.confDir}/ejabberd.cfg test -f ${cfg.confDir}/ejabberd.cfg || 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:${pkgs.coreutils}/bin:${pkgs.bash}/bin; 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
''; '';
}];
exec = "${pkgs.bash}/bin/sh -c 'export PATH=$PATH:${pkgs.ejabberd}/sbin:${pkgs.coreutils}/bin:${pkgs.bash}/bin; cd ~; ejabberdctl --logs ${cfg.logsDir} --spool ${cfg.spoolDir} --config ${cfg.confDir}/ejabberd.cfg start; sleep 1d'";
postStop =
''
${pkgs.ejabberd}/sbin/ejabberdctl stop
'';
}; };
};
} }

View File

@ -1,12 +1,49 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.gnunet;
configFile = with cfg; pkgs.writeText "gnunetd.conf"
''
[PATHS]
GNUNETD_HOME = ${home}
[GNUNETD]
HOSTLISTURL = ${lib.concatStringsSep " " hostLists}
APPLICATIONS = ${lib.concatStringsSep " " applications}
TRANSPORTS = ${lib.concatStringsSep " " transports}
[LOAD]
MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth}
MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth}
HARDUPLIMIT = ${toString load.hardNetUpBandwidth}
MAXCPULOAD = ${toString load.maxCPULoad}
INTERFACES = ${lib.concatStringsSep " " load.interfaces}
[FS]
QUOTA = ${toString fileSharing.quota}
ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"}
[MODULES]
sqstore = sqstore_sqlite
dstore = dstore_sqlite
topology = topology_default
${extraOptions}
'';
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
gnunet = { services.gnunet = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -51,7 +88,6 @@ let
''; '';
}; };
applications = mkOption { applications = mkOption {
default = [ "advertising" "getoption" "fs" "stats" "traffic" ]; default = [ "advertising" "getoption" "fs" "stats" "traffic" ];
example = [ "chat" "fs" ]; example = [ "chat" "fs" ];
@ -140,79 +176,43 @@ let
''; '';
}; };
}; };
}; };
};
in
###### implementation ###### implementation
mkIf config.services.gnunet.enable { config = mkIf config.services.gnunet.enable {
require = [
options
];
users = { users.extraUsers = singleton
extraUsers = [
{ name = "gnunetd"; { name = "gnunetd";
uid = config.ids.uids.gnunetd; uid = config.ids.uids.gnunetd;
description = "GNUnet Daemon User"; description = "GNUnet Daemon User";
home = "/var/empty"; home = "/var/empty";
}
];
}; };
services = { jobAttrs.gnunetd =
extraJobs = [{ { description = "The GNUnet Daemon";
name = "gnunetd";
job = startOn = "network-interfaces/started";
with config.services.gnunet; stopOn = "network-interfaces/stop";
let
inherit (pkgs) lib gnunet;
configFile = pkgs.writeText "gnunetd.conf" ''
[PATHS]
GNUNETD_HOME = ${home}
[GNUNETD] preStart =
HOSTLISTURL = ${lib.concatStringsSep " " hostLists} ''
APPLICATIONS = ${lib.concatStringsSep " " applications} test -d "${cfg.home}" || \
TRANSPORTS = ${lib.concatStringsSep " " transports} ( mkdir -m 755 -p "${cfg.home}" && chown -R gnunetd:users "${cfg.home}")
[LOAD]
MAXNETDOWNBPSTOTAL = ${toString load.maxNetDownBandwidth}
MAXNETUPBPSTOTAL = ${toString load.maxNetUpBandwidth}
HARDUPLIMIT = ${toString load.hardNetUpBandwidth}
MAXCPULOAD = ${toString load.maxCPULoad}
INTERFACES = ${lib.concatStringsSep " " load.interfaces}
[FS]
QUOTA = ${toString fileSharing.quota}
ACTIVEMIGRATION = ${if fileSharing.activeMigration then "YES" else "NO"}
[MODULES]
sqstore = sqstore_sqlite
dstore = dstore_sqlite
topology = topology_default
${extraOptions}
''; '';
in ''
description "The GNUnet Daemon"
start on network-interfaces/started exec =
stop on network-interfaces/stop ''
respawn ${pkgs.gnunet}/bin/gnunetd \
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 "" } \ ${if debug then "--debug" else "" } \
--user="gnunetd" \ --user="gnunetd" \
--config="${configFile}" \ --config="${configFile}" \
--log="${logLevel}" --log="${cfg.logLevel}"
''; '';
}];
}; };
};
} }

View File

@ -1,12 +1,34 @@
{servicesPath, pkgs, config, ...}: { config, pkgs, servicesPath, ... }:
with pkgs.lib;
let
cfg = config.services.gw6c;
gw6cService = import (servicesPath + /gw6c) {
inherit (pkgs) stdenv gw6c coreutils
procps upstart iputils gnused
gnugrep seccure writeScript;
username = cfg.username;
password = cfg.password;
server = cfg.server;
keepAlive = cfg.keepAlive;
everPing = cfg.everPing;
seccureKeys = config.security.seccureKeys;
waitPingableBroker = cfg.waitPingableBroker;
};
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
gw6c = { services.gw6c = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "
@ -67,10 +89,16 @@ let
Whether to wait until tunnel broker returns ICMP echo. Whether to wait until tunnel broker returns ICMP echo.
"; ";
}; };
}; };
};
security = { security.seccureKeys = {
seccureKeys = {
# !!! It's not clear to me (ED) what additional security this
# provides. Passwords shouldn't be in configuration.nix,
# period. You could just place the password in
# /var/blah/password or whatever.
public = mkOption { public = mkOption {
default = /var/elliptic-keys/public; default = /var/elliptic-keys/public;
description = " description = "
@ -91,51 +119,25 @@ let
Private key. Make it string argument, so it is not copied into store. Private key. Make it string argument, so it is not copied into store.
"; ";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf cfg.enable {
cfg = config.services.gw6c;
procps = pkgs.procps;
gw6cService = import (servicesPath + /gw6c) {
inherit (pkgs) stdenv gw6c coreutils
procps upstart iputils gnused
gnugrep seccure writeScript;
username = cfg.username;
password = cfg.password;
server = cfg.server;
keepAlive = cfg.keepAlive;
everPing = cfg.everPing;
seccureKeys = config.security.seccureKeys; jobAttrs.gw6c =
{ description = "Gateway6 client";
waitPingableBroker = cfg.waitPingableBroker; startOn = if cfg.autorun then "network-interfaces/started" else "";
stopOn = "network-interfaces/stop";
exec = "${gw6cService}/bin/control start";
}; };
in
mkIf config.services.gw6c.enable {
require = [
options
];
services = {
extraJobs = [{
name = "gw6c";
users = [];
groups = [];
job = ''
description \"Gateway6 client\"
start on ${ if cfg.autorun then "network-interfaces/started" else "never" }
stop on network-interfaces/stop
respawn ${gw6cService}/bin/control start
'';
}];
}; };
} }

View File

@ -1,12 +1,37 @@
{servicesPath, pkgs, config, ...}: { config, pkgs, servicesPath, ... }:
with pkgs.lib;
let
cfg = config.services.ircdHybrid;
ircdService = import (servicesPath + /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
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
ircdHybrid = { services.ircdHybrid = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -76,55 +101,33 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.ircdHybrid.enable {
cfg = config.services.ircdHybrid;
ircdService = import (servicesPath + /ircd-hybrid) { users.extraUsers = singleton
stdenv = pkgs.stdenv; { name = "ircd";
inherit (pkgs) ircdHybrid coreutils description = "IRCD owner";
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"; users.extraGroups = singleton
{ name = "ircd"; };
in jobAttrs.ircd_hybrid =
{ # name = "ircd-hybrid"; !!! mkIf bug
mkIf config.services.ircdHybrid.enable { description = "IRCD Hybrid server";
require = [
options
];
services = { startOn = "${startingDependency}/started";
extraJobs = [{ stopOn = "${startingDependency}/stop";
name = "ircd-hybrid";
users = [ {
name = "ircd";
description = "IRCD owner.";
} ];
groups = [{name = "ircd";}];
job = ''
description = "IRCD Hybrid server."
start on ${startingDependency}/started exec = "${ircdService}/bin/control start";
stop on ${startingDependency}/stop
respawn ${ircdService}/bin/control start
'';
}];
}; };
};
} }

View File

@ -1,65 +1,62 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
inherit (pkgs) jre openfire coreutils which gnugrep gawk gnused;
startDependency =
if config.services.openfire.usePostgreSQL then "postgresql" else
if config.services.gw6c.enable then "gw6c" else
"network-interfaces";
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
openfire = { services.openfire = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "
Whether to enable OpenFire XMPP server. Whether to enable OpenFire XMPP server.
"; ";
}; };
usePostgreSQL = mkOption { usePostgreSQL = mkOption {
default = true; default = true;
description = " description = "
Whether you use PostgreSQL service for your storage back-end. Whether you use PostgreSQL service for your storage back-end.
"; ";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.openfire.enable {
inherit (pkgs) jre openfire coreutils which gnugrep gawk gnused;
startDependency = if config.services.openfire.usePostgreSQL then assertions = singleton
"postgresql" { assertion = !(config.services.openfire.usePostgreSQL -> config.services.postgresql.enable);
else
if config.services.gw6c.enable then
"gw6c"
else
"network-interfaces";
in
mkIf config.services.openfire.enable {
assertions = [ {
assertion = !(config.services.openfire.usePostgreSQL -> config.services.postgresql.enable);
message = "openfire assertion failed"; message = "openfire assertion failed";
} ]; };
require = [ jobAttrs.openfire =
options { description = "OpenFire XMPP server";
];
startOn = "${startDependency}/started";
stopOn = "shutdown";
services = { script =
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 PATH=${jre}/bin:${openfire}/bin:${coreutils}/bin:${which}/bin:${gnugrep}/bin:${gawk}/bin:${gnused}/bin
export HOME=/tmp export HOME=/tmp
mkdir /var/log/openfire || true mkdir /var/log/openfire || true
@ -70,8 +67,9 @@ mkIf config.services.openfire.enable {
fi fi
done done
openfire start openfire start
end script ''; # */
'';
}];
}; };
};
} }

View File

@ -1,20 +1,67 @@
{ config, pkgs, ... }:
{pkgs, config, ...}: with pkgs.lib;
let
cfg = config.services.openvpn;
inherit (pkgs) openvpn;
PATH = "${pkgs.iptables}/sbin:${pkgs.coreutils}/bin:${pkgs.iproute}/sbin:${pkgs.nettools}/sbin";
makeOpenVPNJob = cfg :
let
upScript = ''
#!/bin/sh
exec &> /var/log/openvpn-${cfg.id}-up
PATH=${PATH}
${cfg.up}
'';
downScript = ''
#!/bin/sh
exec &> /var/log/openvpn-${cfg.id}-down
PATH=${PATH}
${cfg.down}
'';
configFile = pkgs.writeText "openvpn-config-${cfg.id}"
''
${if cfg ? up || cfg ? down then "script-security 2" else ""}
${cfg.config}
${if cfg ? up then "up ${pkgs.writeScript "openvpn-${cfg.id}-up" upScript}" else "" }
${if cfg ? down then "down ${pkgs.writeScript "openvpn-${cfg.id}-down" downScript}" else "" }
'';
in {
description = "OpenVPN-${cfg.id}";
startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
environment = { PATH = "${pkgs.coreutils}/bin"; };
script =
''
exec &> /var/log/openvpn-${cfg.id}
${config.system.sbin.modprobe} tun || true
${openvpn}/sbin/openvpn --config ${configFile}
'';
};
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
openvpn = { services.openvpn = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "Whether to enable OpenVPN.";
Whether to enable the Secure Shell daemon, which allows secure
remote logins.
";
}; };
servers = mkOption { servers = mkOption {
example = [ example = [
{ {
@ -52,6 +99,7 @@ let
} }
]; ];
default = []; default = [];
# !!! clean up this description please
description = '' description = ''
openvpn instances to be run. Each will be put into an extra job named openvpn-{id} openvpn instances to be run. Each will be put into an extra job named openvpn-{id}
@ -63,72 +111,18 @@ let
--fragment XXX --mssfix YYY. --fragment XXX --mssfix YYY.
''; '';
}; };
};
};
}; };
};
modprobe = config.system.sbin.modprobe;
###### implementation ###### implementation
cfg = config.services.openvpn; config = mkIf cfg.enable {
inherit (pkgs) openvpn; jobAttrs = listToAttrs (map (c: nameValuePair "openvpn-${cfg.id}" (makeOpenVPNJob c)) cfg.servers);
inherit (builtins) hasAttr;
PATH="${pkgs.iptables}/sbin:${pkgs.coreutils}/bin:${pkgs.iproute}/sbin:${pkgs.nettools}/sbin";
makeOpenVPNJob = cfg :
let
upScript = ''
#!/bin/sh
exec &> /var/log/openvpn-${cfg.id}-up
PATH=${PATH}
${cfg.up}
'';
downScript = ''
#!/bin/sh
exec &> /var/log/openvpn-${cfg.id}-down
PATH=${PATH}
${cfg.down}
'';
configFile = pkgs.writeText "openvpn-config-${cfg.id}" ''
${if hasAttr "up" cfg || hasAttr "down" cfg then "script-security 2" else ""}
${cfg.config}
${if hasAttr "up" cfg then "up ${pkgs.writeScript "openvpn-${cfg.id}-up" upScript}" else "" }
${if hasAttr "down" cfg then "down ${pkgs.writeScript "openvpn-${cfg.id}-down" downScript}" else "" }
'';
in {
name = "openvpn-${cfg.id}";
job = ''
description "OpenVPN-${cfg.id}"
start on network-interfaces/started
stop on network-interfaces/stop
PATH=${pkgs.coreutils}/bin
respawn
script
exec &> /var/log/openvpn-${cfg.id}
${modprobe} tun || true
${openvpn}/sbin/openvpn --config ${configFile}
end script
'';
}; };
in
mkIf cfg.enable {
require = [
options
];
services = {
extraJobs = map makeOpenVPNJob cfg.servers;
};
} }

View File

@ -1,12 +1,24 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
uid = config.ids.uids.portmap;
gid = config.ids.gids.portmap;
portmap = pkgs.portmap.override { daemonUID = uid; daemonGID = gid; };
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
portmap = { services.portmap = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = '' description = ''
@ -31,59 +43,42 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let uid = config.ids.uids.portmap; config = mkIf config.services.portmap.enable {
gid = config.ids.gids.portmap;
in
mkIf config.services.portmap.enable { users.extraUsers = singleton
require = [
options
];
users = {
extraUsers = [
{ name = "portmap"; { name = "portmap";
inherit uid; inherit uid;
description = "portmap daemon user"; description = "portmap daemon user";
home = "/var/empty"; home = "/var/empty";
}
];
extraGroups = [
{ name = "portmap";
inherit gid;
}
];
}; };
services = { users.extraGroups = singleton
extraJobs = [{ { name = "portmap";
name = "portmap"; inherit gid;
};
jobAttrs.portmap =
{ description = "ONC RPC portmap";
job = startOn = "network-interfaces/started";
let portmap = pkgs.portmap.override { daemonUID = uid; daemonGID = gid; }; stopOn = "network-interfaces/stop";
in
exec =
'' ''
description "ONC RPC portmap" ${portmap}/sbin/portmap -f \
start on network-interfaces/started
stop on network-interfaces/stop
respawn ${portmap}/sbin/portmap -f \
${if config.services.portmap.chroot == "" ${if config.services.portmap.chroot == ""
then "" then ""
else "-t \"${config.services.portmap.chroot}\""} \ else "-t \"${config.services.portmap.chroot}\""} \
${if config.services.portmap.verbose then "-v" else ""} ${if config.services.portmap.verbose then "-v" else ""}
''; '';
}];
}; };
};
} }

View File

@ -1,12 +1,22 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
inherit (pkgs) lsh;
cfg = config.services.lshd;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
lshd = { services.lshd = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -96,43 +106,27 @@ let
an executable implementing it. an executable implementing it.
''; '';
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf cfg.enable {
inherit (pkgs) lsh; jobAttrs.lshd =
inherit (pkgs.lib) concatStrings concatStringsSep head tail; { description = "GNU lshd SSH2 daemon";
lshdConfig = config.services.lshd; startOn = "network-interfaces/started";
stopOn = "network-interfaces/stop";
nssModules = config.system.nssModules.list; environment =
{ LD_LIBRARY_PATH = config.system.nssModules.path; };
nssModulesPath = config.system.nssModules.path; preStart =
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 /etc/lsh || mkdir -m 0755 -p /etc/lsh
test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
@ -144,14 +138,16 @@ mkIf config.services.lshd.enable {
${lsh}/bin/lsh-make-seed -o /var/spool/lsh/yarrow-seed-file ${lsh}/bin/lsh-make-seed -o /var/spool/lsh/yarrow-seed-file
fi fi
if ! test -f "${hostKey}" if ! test -f "${cfg.hostKey}"
then then
${lsh}/bin/lsh-keygen --server | \ ${lsh}/bin/lsh-keygen --server | \
${lsh}/bin/lsh-writekey --server -o "${hostKey}" ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
fi fi
end script '';
respawn ${lsh}/sbin/lshd --daemonic \ exec = with cfg;
''
${lsh}/sbin/lshd --daemonic \
--password-helper="${lsh}/sbin/lsh-pam-checkpw" \ --password-helper="${lsh}/sbin/lsh-pam-checkpw" \
-p ${toString portNumber} \ -p ${toString portNumber} \
${if interfaces == [] then "" ${if interfaces == [] then ""
@ -171,8 +167,8 @@ mkIf config.services.lshd.enable {
(head (tail pair))) (head (tail pair)))
subsystems)} subsystems)}
''; '';
};
};
}
];
};
} }

View File

@ -1,92 +1,11 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### interface with pkgs.lib;
let
inherit (pkgs.lib) mkOption mkIf;
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.
";
};
anonymousUserHome = mkOption {
default = "/home/ftp";
description = "
Path to anonymous user data.
";
};
localUsers = mkOption {
default = false;
description = "
Whether to enable FTP for the local users.
";
};
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.
";
};
chrootlocalUser = mkOption {
default = false;
description = "
Whether u can like out of ur home dir.
";
};
userlistEnable = mkOption {
default = false;
description = "
Whether users are included.
";
};
userlistDeny = mkOption {
default = false;
description = "
Whether users are excluded.
";
};
};
};
};
in
###### implementation
let let
inherit (config.services.vsftpd) anonymousUser anonymousUserHome localUsers writeEnable anonymousUploadEnable anonymousMkdirEnable cfg = config.services.vsftpd;
chrootlocalUser userlistEnable userlistDeny;
inherit (pkgs) vsftpd; inherit (pkgs) vsftpd;
yesNoOption = p : name : yesNoOption = p : name :
@ -94,67 +13,123 @@ let
in in
mkIf config.services.vsftpd.enable { {
require = [
options
];
users = { ###### interface
extraUsers = [
{ name = "vsftpd"; 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.";
};
anonymousUserHome = mkOption {
default = "/home/ftp";
description = "Path to anonymous user data.";
};
localUsers = mkOption {
default = false;
description = "Whether to enable FTP for local users.";
};
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.";
};
chrootlocalUser = mkOption {
default = false;
description = "Whether local users are confined to their home directory.";
};
userlistEnable = mkOption {
default = false;
description = "Whether users are included.";
};
userlistDeny = mkOption {
default = false;
description = "Whether users are excluded.";
};
};
};
###### implementation
config = mkIf cfg.enable {
users.extraUsers =
[ { name = "vsftpd";
uid = config.ids.uids.vsftpd; uid = config.ids.uids.vsftpd;
description = "VSFTPD user"; description = "VSFTPD user";
home = "/homeless-shelter"; home = "/homeless-shelter";
} }
] ++ pkgs.lib.optional anonymousUser ] ++ pkgs.lib.optional cfg.anonymousUser
{ name = "ftp"; { name = "ftp";
uid = config.ids.uids.ftp; uid = config.ids.uids.ftp;
group = "ftp"; group = "ftp";
description = "Anonymous ftp user"; description = "Anonymous FTP user";
home = anonymousUserHome; home = cfg.anonymousUserHome;
}; };
extraGroups = [ users.extraGroups = singleton
{ name = "ftp"; { name = "ftp";
gid = config.ids.gids.ftp; gid = config.ids.gids.ftp;
}
];
}; };
services = { jobAttrs.vsftpd =
extraJobs = [{ { description = "vsftpd server";
name = "vsftpd";
job = '' startOn = "network-interfaces/started";
description "vsftpd server" stopOn = "network-interfaces/stop";
start on network-interfaces/started preStart =
stop on network-interfaces/stop ''
# !!! Why isn't this generated in the normal way?
start script
cat > /etc/vsftpd.conf <<EOF cat > /etc/vsftpd.conf <<EOF
${yesNoOption anonymousUser "anonymous_enable"} ${yesNoOption cfg.anonymousUser "anonymous_enable"}
${yesNoOption localUsers "local_enable"} ${yesNoOption cfg.localUsers "local_enable"}
${yesNoOption writeEnable "write_enable"} ${yesNoOption cfg.writeEnable "write_enable"}
${yesNoOption anonymousUploadEnable "anon_upload_enable"} ${yesNoOption cfg.anonymousUploadEnable "anon_upload_enable"}
${yesNoOption anonymousMkdirEnable "anon_mkdir_write_enable"} ${yesNoOption cfg.anonymousMkdirEnable "anon_mkdir_write_enable"}
${yesNoOption chrootlocalUser "chroot_local_user"} ${yesNoOption cfg.chrootlocalUser "chroot_local_user"}
${yesNoOption userlistEnable "userlist_enable"} ${yesNoOption cfg.userlistEnable "userlist_enable"}
${yesNoOption userlistDeny "userlist_deny"} ${yesNoOption cfg.userlistDeny "userlist_deny"}
background=NO background=NO
listen=YES listen=YES
nopriv_user=vsftpd nopriv_user=vsftpd
secure_chroot_dir=/var/ftp/empty secure_chroot_dir=/var/ftp/empty
EOF EOF
mkdir -p ${anonymousUserHome} && mkdir -p ${cfg.anonymousUserHome}
chown -R ftp:ftp ${anonymousUserHome} chown -R ftp:ftp ${cfg.anonymousUserHome}
end script
respawn ${vsftpd}/sbin/vsftpd /etc/vsftpd.conf
''; '';
}]; exec = "${vsftpd}/sbin/vsftpd /etc/vsftpd.conf";
}; };
};
} }

View File

@ -1,41 +1,13 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### interface with pkgs.lib;
let
inherit (pkgs.lib) mkOption mkIf;
options = {
services = {
printing = {
enable = mkOption {
default = false;
description = "
Whether to enable printing support through the CUPS daemon.
";
};
bindirCmds = mkOption {
default = "";
description = "
add commands adding additional symlinks to the bindir such as bjnp
";
};
};
};
};
in
###### implementation
let let
logDir = "/var/log/cups";
inherit (pkgs) cups; inherit (pkgs) cups;
logDir = "/var/log/cups";
modprobe = config.system.sbin.modprobe; modprobe = config.system.sbin.modprobe;
cfg = config.services.printing; cfg = config.services.printing;
@ -45,7 +17,8 @@ let
# we can't update ${cups}/lib/cups itself, we create a symlink tree # we can't update ${cups}/lib/cups itself, we create a symlink tree
# here and add the additional programs. The ServerBin directive in # here and add the additional programs. The ServerBin directive in
# cupsd.conf tells cupsd to use this tree. # cupsd.conf tells cupsd to use this tree.
bindir = pkgs.runCommand "cups-progs" {} '' bindir = pkgs.runCommand "cups-progs" {}
''
ensureDir $out/lib/cups ensureDir $out/lib/cups
ln -s ${cups}/lib/cups/* $out/lib/cups/ ln -s ${cups}/lib/cups/* $out/lib/cups/
@ -68,7 +41,8 @@ let
''; # */ ''; # */
cupsdConfig = pkgs.writeText "cupsd.conf" '' cupsdConfig = pkgs.writeText "cupsd.conf"
''
LogLevel debug LogLevel debug
SystemGroup root SystemGroup root
@ -137,11 +111,37 @@ let
in in
{
mkIf config.services.printing.enable { ###### interface
require = [
options options = {
];
services.printing = {
enable = mkOption {
default = false;
description = ''
Whether to enable printing support through the CUPS daemon.
'';
};
bindirCmds = mkOption {
default = "";
description = ''
Additional commands executed while creating the directory
containing the CUPS server binaries.
'';
};
};
};
###### implementation
config = mkIf config.services.printing.enable {
environment.systemPackages = [cups]; environment.systemPackages = [cups];
@ -155,25 +155,25 @@ mkIf config.services.printing.enable {
} }
]; ];
services.extraJobs = pkgs.lib.singleton jobAttrs.cupsd =
{ name = "cupsd"; { description = "CUPS printing daemon";
job = '' startOn = "network-interfaces/started";
description "CUPS printing daemon" stopOn = "network-interfaces/stop";
start on network-interfaces/started preStart =
stop on network-interfaces/stop ''
start script
mkdir -m 0755 -p ${logDir} mkdir -m 0755 -p ${logDir}
mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/cache/cups
mkdir -m 0700 -p /var/spool/cups mkdir -m 0700 -p /var/spool/cups
# Make USB printers show up. # Make USB printers show up.
${modprobe}/sbin/modprobe usblp || true ${modprobe}/sbin/modprobe usblp || true
end script
respawn ${cups}/sbin/cupsd -c ${cupsdConfig} -F
''; '';
exec = "${cups}/sbin/cupsd -c ${cupsdConfig} -F";
}; };
};
} }

View File

@ -1,12 +1,29 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
inherit (config.services) jobsTags;
# Put all the system cronjobs together.
systemCronJobsFile = pkgs.writeText "system-crontab"
''
SHELL=${pkgs.bash}/bin/sh
PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin:${pkgs.su}/bin
MAILTO="${config.services.cron.mailto}"
${pkgs.lib.concatStrings (map (job: job + "\n") config.services.cron.systemCronJobs)}
'';
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption;
options = { options = {
services = {
cron = { services.cron = {
mailto = mkOption { mailto = mkOption {
default = ""; default = "";
@ -32,61 +49,34 @@ let
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let
inherit (config.services) jobsTags;
# Put all the system cronjobs together. config = {
systemCronJobs =
config.services.cron.systemCronJobs;
systemCronJobsFile = pkgs.writeText "system-crontab" '' environment.etc = singleton
SHELL=${pkgs.bash}/bin/sh
PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin:${pkgs.su}/bin
MAILTO="${config.services.cron.mailto}"
${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)}
'';
in
{
require = [
# ../upstart-jobs/default.nix # config.services.extraJobs
# ? # config.time.timeZone
# ? # config.environment.etc
# ? # config.environment.extraPackages
options
];
environment = {
etc = [
# The system-wide crontab. # The system-wide crontab.
{ source = systemCronJobsFile; { source = systemCronJobsFile;
target = "crontab"; target = "crontab";
mode = "0600"; # Cron requires this. mode = "0600"; # Cron requires this.
}
];
systemPackages = [pkgs.cron];
}; };
services = { environment.systemPackages = [pkgs.cron];
extraJobs = [{
name = "cron";
job = '' jobAttrs.cron =
description "Cron daemon" { description = "Cron daemon";
start on startup startOn = "startup";
stop on shutdown stopOn = "shutdown";
# Needed to interpret times in the local timezone. # Needed to interpret times in the local timezone.
env TZ=${config.time.timeZone} environment = { TZ = config.time.timeZone; };
start script preStart =
''
mkdir -m 710 -p /var/cron mkdir -m 710 -p /var/cron
# By default, allow all users to create a crontab. This # By default, allow all users to create a crontab. This
@ -94,10 +84,11 @@ in
if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
touch /var/cron/cron.deny touch /var/cron/cron.deny
fi fi
end script
respawn ${pkgs.cron}/sbin/cron -n
''; '';
}];
exec = "${pkgs.cron}/sbin/cron -n";
}; };
};
} }

View File

@ -1,76 +1,27 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### interface
let let
inherit (pkgs.lib) mkOption concatStringsSep;
inherit (pkgs) writeText;
options = {
services = {
fcron = {
enable = mkOption {
default = false;
description = ''Whether to enable the `fcron' daemon.
From its docs: "fcron does both the job of Vixie Cron and anacron, but does even more and better".
It can trigger actions even if the event has passed due to shutdown for example.
TODO: add supoprt for fcron.allow and fcron.deny
Of course on cron daemon is enough.. So if fcron works fine there should be a system option systemCron="fcron or cron"
There are (or have been) some security issues.
I haven't yet checked wether they have been resolved.
For now you should trust the users registering crontab files.
I think gentoo has them listed.
'';
};
allow = mkOption {
default = [];
description = ''
Users allowed to use fcrontab and fcrondyn (one name per line, special name "all" acts for everyone)
nix adds username "root" for you.
'';
};
deny = mkOption {
default = [];
description = " same as allow but deny ";
};
maxSerialJobs = mkOption {
default = 1;
description = "maximum number of serial jobs which can run simultaneously (-m)";
};
queuelen = mkOption {
default = "";
description = "number of jobs the serial queue and the lavg queue can contain - empty to net set this number (-q)";
};
systab = mkOption {
default = "";
description = ''
The "system" crontab contents..
'';
};
};
};
};
in
###### implementation
let
# Put all the system cronjobs together. # Put all the system cronjobs together.
# TODO allow using fcron only.. # TODO allow using fcron only..
#systemCronJobs = #systemCronJobs =
# config.services.cron.systemCronJobs; # config.services.cron.systemCronJobs;
cfg = config.services.fcron; cfg = config.services.fcron;
ifEnabled = if cfg.enable then pkgs.lib.id else (x : []);
queuelen = if cfg.queuelen == "" then "" else "-q ${toString cfg.queuelen}"; queuelen = if cfg.queuelen == "" then "" else "-q ${toString cfg.queuelen}";
# shell is set to /sh in config.. # shell is set to /sh in config..
# ${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)} # ${pkgs.lib.concatStrings (map (job: job + "\n") systemCronJobs)}
systemCronJobsFile = pkgs.writeText "fcron-systab" '' systemCronJobsFile = pkgs.writeText "fcron-systab"
''
SHELL=${pkgs.bash}/bin/sh SHELL=${pkgs.bash}/bin/sh
PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin PATH=${pkgs.coreutils}/bin:${pkgs.findutils}/bin:${pkgs.gnused}/bin
''; '';
allowdeny = target: users : { allowdeny = target: users:
source = writeText "fcron.${target}" (concatStringsSep "\n" users); { source = pkgs.writeText "fcron.${target}" (concatStringsSep "\n" users);
target = "fcron.${target}"; target = "fcron.${target}";
mode = "600"; # fcron has some security issues.. So I guess this is most safe mode = "600"; # fcron has some security issues.. So I guess this is most safe
}; };
@ -78,21 +29,58 @@ let
in in
{ {
require = [
# ../upstart-jobs/default.nix # config.services.extraJobs
# ? # config.time.timeZone
# ? # config.environment.etc
# ? # config.environment.extraPackages
# ? # config.environment.cleanStart
options
];
environment = { ###### interface
etc = ifEnabled [
(allowdeny "allow" (["root"] ++ cfg.allow)) options = {
services.fcron = {
enable = mkOption {
default = false;
description = "Whether to enable the `fcron' daemon.";
};
allow = mkOption {
default = [];
description = ''
Users allowed to use fcrontab and fcrondyn (one name per line, "all" for everyone).
'';
};
deny = mkOption {
default = [];
description = "Users forbidden from using fcron.";
};
maxSerialJobs = mkOption {
default = 1;
description = "Maximum number of serial jobs which can run simultaneously.";
};
queuelen = mkOption {
default = "";
description = "Number of jobs the serial queue and the lavg queue can contain - empty to net set this number (-q)";
};
systab = mkOption {
default = "";
description = ''The "system" crontab contents.'';
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.etc =
[ (allowdeny "allow" (["root"] ++ cfg.allow))
(allowdeny "deny" cfg.deny) (allowdeny "deny" cfg.deny)
# see man 5 fcron.conf # see man 5 fcron.conf
{ source = writeText "fcon.conf" '' { source = pkgs.writeText "fcon.conf" ''
fcrontabs = /var/spool/fcron fcrontabs = /var/spool/fcron
pidfile = /var/run/fcron.pid pidfile = /var/run/fcron.pid
fifofile = /var/run/fcron.fifo fifofile = /var/run/fcron.fifo
@ -107,29 +95,28 @@ in
} }
]; ];
systemPackages = ifEnabled [pkgs.fcron]; environment.systemPackages = [ pkgs.fcron ];
jobAttrs.fcron =
{ description = "fcron daemon";
startOn = "startup";
stopOn = "shutdown";
environment =
{ PATH = "/var/run/current-system/sw/bin";
}; };
services = { preStart =
extraJobs = ifEnabled [{ ''
name = "fcron";
job = ''
description "fcron daemon"
start on startup
stop on shutdown
env PATH=/var/run/current-system/sw/bin
start script
${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron ${pkgs.coreutils}/bin/mkdir -m 0700 -p /var/spool/fcron
# load system crontab file # load system crontab file
${pkgs.fcron}/bin/fcrontab -u systab ${writeText "systab" cfg.systab} ${pkgs.fcron}/bin/fcrontab -u systab ${pkgs.writeText "systab" cfg.systab}
end script
respawn ${pkgs.fcron}/sbin/fcron -f -m ${toString cfg.maxSerialJobs} ${queuelen}
''; '';
}];
exec = "${pkgs.fcron}/sbin/fcron -f -m ${toString cfg.maxSerialJobs} ${queuelen}";
}; };
};
} }

View File

@ -1,58 +1,52 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.gpm;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption;
options = { options = {
services = {
gpm = { services.gpm = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = ''
Whether to enable general purpose mouse daemon. Whether to enable GPM, the General Purpose Mouse daemon,
"; which enables mouse support in virtual consoles.
};
protocol = mkOption {
default = "ps/2";
description = "
Mouse protocol to use.
";
};
};
};
};
in
###### implementation
let
cfg = config.services.gpm;
inherit (pkgs.lib) mkIf;
gpm = pkgs.gpm;
gpmBin = "${gpm}/sbin/gpm";
job = {
name = "gpm";
job = ''
description = "General purpose mouse"
start on udev
stop on shutdown
respawn ${gpmBin} -m /dev/input/mice -t ${cfg.protocol} -D &>/dev/null
''; '';
}; };
in
mkIf cfg.enable { protocol = mkOption {
require = [ default = "ps/2";
# ../upstart-jobs/default.nix # config.services.extraJobs description = "Mouse protocol to use.";
# /etc/security/console.perms (should be generated ?)
options
];
services = {
extraJobs = [job];
}; };
};
};
###### implementation
config = mkIf cfg.enable {
jobAttrs.gpm =
{ description = "General purpose mouse";
startOn = "udev";
stopOn = "shutdown";
exec = "${pkgs.gpm}/sbin/gpm -m /dev/input/mice -t ${cfg.protocol} -D &>/dev/null";
};
};
} }

View File

@ -1,12 +1,26 @@
{servicesPath, pkgs, config, ...}: { config, pkgs, servicesPath, ... }:
with pkgs.lib;
let
cfg = config.services.jboss;
jbossService = import (servicesPath + /jboss) {
inherit (pkgs) stdenv jboss su;
inherit (cfg) tempDir logDir libUrl deployDir serverDir user useJK;
};
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
jboss = { services.jboss = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = "Whether to enable jboss"; description = "Whether to enable jboss";
@ -46,37 +60,22 @@ let
default = false; default = false;
description = "Whether to use to connector to the Apache HTTP server"; description = "Whether to use to connector to the Apache HTTP server";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let
cfg = config.services.jboss; config = mkIf config.services.jboss.enable {
jbossService = import (servicesPath + /jboss) {
inherit (pkgs) stdenv jboss su; jobAttrs.jboss =
inherit (cfg) tempDir logDir libUrl deployDir serverDir user useJK; { description = "JBoss server";
exec = "${jbossService}/bin/control start";
}; };
in
mkIf config.services.jboss.enable {
require = [
options
];
services = {
extraJobs = [{
name = "jboss";
job = ''
description \"JBoss server\"
stop on shutdown
respawn ${jbossService}/bin/control start
'';
}];
}; };
} }

View File

@ -1,12 +1,21 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.tomcat;
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
tomcat = { services.tomcat = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = "Whether to enable Apache Tomcat"; description = "Whether to enable Apache Tomcat";
@ -58,6 +67,7 @@ let
}; };
axis2 = { axis2 = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = "Whether to enable an Apache Axis2 container"; description = "Whether to enable an Apache Axis2 container";
@ -67,48 +77,38 @@ let
default = []; default = [];
description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2"; description = "List containing AAR files or directories with AAR files which are web services to be deployed on Axis2";
}; };
}; };
}; };
}; };
};
in
###### implementation ###### implementation
let config = mkIf config.services.tomcat.enable {
cfg = config.services.tomcat;
in
mkIf config.services.tomcat.enable { users.extraGroups = singleton
require = [
options
];
services = {
extraJobs = [{
name = "tomcat";
groups = [
{ name = "tomcat"; { name = "tomcat";
gid = config.ids.gids.tomcat; gid = config.ids.gids.tomcat;
} };
];
users = [ users.extraUsers = singleton
{ name = "tomcat"; { name = "tomcat";
uid = config.ids.uids.tomcat; uid = config.ids.uids.tomcat;
description = "Tomcat user"; description = "Tomcat user";
home = "/homeless-shelter"; home = "/homeless-shelter";
} };
];
job = '' jobAttrs.tomcat =
description "Apache Tomcat server" { description = "Apache Tomcat server";
start on network-interface/started startOn = "network-interface/started";
stop on network-interfaces/stop stopOn = "network-interfaces/stop";
start script preStart =
''
# Create the base directory # Create the base directory
mkdir -p ${cfg.baseDir} mkdir -p ${cfg.baseDir}
@ -304,15 +304,21 @@ mkIf config.services.tomcat.enable {
done done
'' ''
else ""} else ""}
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' exec =
''
${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 postStop =
''
echo "Stopping tomcat..." 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 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
''; '';
}];
}; };
};
} }

View File

@ -1,54 +1,54 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let
configFile = ./xfs.conf;
startingDependency =
if config.services.gw6c.enable && config.services.gw6c.autorun
then "gw6c"
else "network-interfaces";
in
{
###### interface ###### interface
let
inherit (pkgs.lib) mkOption mkIf;
options = { options = {
services = {
xfs = { services.xfs = {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = " description = "Whether to enable the X Font Server.";
Whether to enable the X Font Server.
";
}; };
}; };
}; };
};
in
###### implementation ###### implementation
config = mkIf config.services.xfs.enable {
let assertions = singleton
configFile = ./xfs.conf; { assertion = config.fonts.enableFontDir;
startingDependency = if config.services.gw6c.enable && config.services.gw6c.autorun then "gw6c" else "network-interfaces"; message = "Please enable fontDir (fonts.enableFontDir) to use xfs.";
in
mkIf config.services.xfs.enable {
assertions = [ { assertion = config.fonts.enableFontDir; message = "Please enable fontDir (fonts.enableFontDir) to use xfs."; } ];
require = [
options
];
services = {
extraJobs = [ (rec {
name = "xfs";
groups = [];
users = [];
job = ''
description "X Font Server"
start on ${startingDependency}/started
stop on shutdown
respawn ${pkgs.xorg.xfs}/bin/xfs -config ${configFile}
'';
})];
}; };
jobAttrs.xfs =
{ description = "X Font Server";
startOn = "${startingDependency}/started";
stopOn = "shutdown";
exec = "${pkgs.xorg.xfs}/bin/xfs -config ${configFile}";
};
};
} }

View File

@ -1,20 +1,18 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### implementation ###### implementation
{ {
jobAttrs.ctrl_alt_delete =
{ name = "ctrl-alt-delete";
services = { startOn = "ctrlaltdel";
extraJobs = [{
name = "ctrl-alt-delete";
job = '' task = true;
on ctrlaltdel
script script =
''
shutdown -r now 'Ctrl-Alt-Delete pressed' shutdown -r now 'Ctrl-Alt-Delete pressed'
end script
''; '';
}];
}; };
} }

View File

@ -1,19 +1,20 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
###### implementation ###### implementation
let let
inherit (pkgs) bash utillinux; inherit (pkgs) bash utillinux;
jobFun = event : { jobFun = event:
name = "sys-" + event; { startOn = event;
job = '' task = true;
start on ${event}
script script =
''
set +e # continue in case of errors set +e # continue in case of errors
exec < /dev/tty1 > /dev/tty1 2>&1 exec < /dev/tty1 > /dev/tty1 2>&1
@ -109,16 +110,12 @@ let
sleep 1 sleep 1
exec halt -f -p exec halt -f -p
fi fi
end script
''; '';
}; };
in in
{ {
services = { jobAttrs = listToAttrs (map (n: nameValuePair "sys-${n}" (jobFun n))
extraJobs = map jobFun ["reboot" "halt" "system-halt" "power-off"]; [ "reboot" "halt" "system-halt" "power-off" ] );
};
} }

View File

@ -1,24 +1,22 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### implementation ###### implementation
{ {
services = { jobAttrs.maintenance_shell =
extraJobs = [{ { name = "maintenance-shell";
name = "maintenance-shell";
job = '' startOn = [ "maintenance" "stalled" ];
start on maintenance
start on stalled
script task = true;
script =
''
exec < /dev/tty1 > /dev/tty1 2>&1 exec < /dev/tty1 > /dev/tty1 2>&1
echo \"\" echo \
echo \"<<< MAINTENANCE SHELL >>>\" echo "<<< MAINTENANCE SHELL >>>"
echo \"\" echo ""
exec ${pkgs.bash}/bin/sh exec ${pkgs.bash}/bin/sh
end script
''; '';
}];
}; };
} }

View File

@ -327,7 +327,7 @@ in
} }
]; ];
# see test/test-upstart-job.sh (!!! check whether this still works) # !!! fix this
tests.upstartJobs = { recurseForDerivations = true; } // tests.upstartJobs = { recurseForDerivations = true; } //
builtins.listToAttrs (map (job: { builtins.listToAttrs (map (job: {
name = removePrefix "upstart-" job.name; name = removePrefix "upstart-" job.name;

View File

@ -1,117 +1,9 @@
{pkgs, config, ...}: { config, pkgs, ... }:
with pkgs.lib;
let let
###### interface
inherit (pkgs.lib) mkOption types;
options = {
fileSystems = mkOption {
example = [
{ mountPoint = "/";
device = "/dev/hda1";
}
{ mountPoint = "/data";
device = "/dev/hda2";
fsType = "ext3";
options = "data=journal";
}
{ mountPoint = "/bigdisk";
label = "bigdisk";
}
];
description = "
The file systems to be mounted. It must include an entry for
the root directory (<literal>mountPoint = \"/\"</literal>). Each
entry in the list is an attribute set with the following fields:
<literal>mountPoint</literal>, <literal>device</literal>,
<literal>fsType</literal> (a file system type recognised by
<command>mount</command>; defaults to
<literal>\"auto\"</literal>), and <literal>options</literal>
(the mount options passed to <command>mount</command> using the
<option>-o</option> flag; defaults to <literal>\"defaults\"</literal>).
Instead of specifying <literal>device</literal>, you can also
specify a volume label (<literal>label</literal>) for file
systems that support it, such as ext2/ext3 (see <command>mke2fs
-L</command>).
<literal>autocreate</literal> forces <literal>mountPoint</literal> to be created with
<command>mkdir -p</command> .
";
type = types.nullOr (types.list types.optionSet);
options = {
mountPoint = mkOption {
example = "/mnt/usb";
type = types.uniq types.string;
description = "
Location of the mounted the file system.
";
};
device = mkOption {
default = null;
example = "/dev/sda";
type = types.uniq (types.nullOr types.string);
description = "
Location of the device.
";
};
label = mkOption {
default = null;
example = "root-partition";
type = types.uniq (types.nullOr types.string);
description = "
Label of the device (if any).
";
};
fsType = mkOption {
default = "auto";
example = "ext3";
type = types.uniq types.string;
description = "
Type of the file system.
";
};
options = mkOption {
default = "defaults,relatime";
example = "data=journal";
type = types.string;
merge = pkgs.lib.concatStringsSep ",";
description = "
Option used to mount the file system.
";
};
autocreate = mkOption {
default = false;
type = types.bool;
description = "
Automatically create the mount point defined in
<option>fileSystems.*.mountPoint</option>.
";
};
};
};
system.sbin.mount = mkOption {
internal = true;
default = pkgs.utillinuxng;
description = "
Package containing mount and umount.
";
};
};
###### implementation
fileSystems = config.fileSystems; fileSystems = config.fileSystems;
mountPoints = map (fs: fs.mountPoint) fileSystems; mountPoints = map (fs: fs.mountPoint) fileSystems;
devices = map (fs: if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fileSystems; devices = map (fs: if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fileSystems;
@ -120,12 +12,8 @@ let
autocreates = map (fs: fs.autocreate) fileSystems; autocreates = map (fs: fs.autocreate) fileSystems;
mount = config.system.sbin.mount; mount = config.system.sbin.mount;
job = '' task =
start on startup ''
start on new-devices
start on ip-up
script
PATH=${pkgs.e2fsprogs}/sbin:${pkgs.utillinuxng}/sbin:$PATH PATH=${pkgs.e2fsprogs}/sbin:${pkgs.utillinuxng}/sbin:$PATH
mountPoints=(${toString mountPoints}) mountPoints=(${toString mountPoints})
@ -222,21 +110,137 @@ let
done done
done done
end script
''; '';
in in
{ {
require = [options];
services = { ###### interface
extraJobs = [{
name = "filesystems"; options = {
inherit job;
}]; fileSystems = mkOption {
example = [
{ mountPoint = "/";
device = "/dev/hda1";
}
{ mountPoint = "/data";
device = "/dev/hda2";
fsType = "ext3";
options = "data=journal";
}
{ mountPoint = "/bigdisk";
label = "bigdisk";
}
];
description = "
The file systems to be mounted. It must include an entry for
the root directory (<literal>mountPoint = \"/\"</literal>). Each
entry in the list is an attribute set with the following fields:
<literal>mountPoint</literal>, <literal>device</literal>,
<literal>fsType</literal> (a file system type recognised by
<command>mount</command>; defaults to
<literal>\"auto\"</literal>), and <literal>options</literal>
(the mount options passed to <command>mount</command> using the
<option>-o</option> flag; defaults to <literal>\"defaults\"</literal>).
Instead of specifying <literal>device</literal>, you can also
specify a volume label (<literal>label</literal>) for file
systems that support it, such as ext2/ext3 (see <command>mke2fs
-L</command>).
<literal>autocreate</literal> forces <literal>mountPoint</literal> to be created with
<command>mkdir -p</command> .
";
type = types.nullOr (types.list types.optionSet);
options = {
mountPoint = mkOption {
example = "/mnt/usb";
type = types.uniq types.string;
description = "
Location of the mounted the file system.
";
}; };
device = mkOption {
default = null;
example = "/dev/sda";
type = types.uniq (types.nullOr types.string);
description = "
Location of the device.
";
};
label = mkOption {
default = null;
example = "root-partition";
type = types.uniq (types.nullOr types.string);
description = "
Label of the device (if any).
";
};
fsType = mkOption {
default = "auto";
example = "ext3";
type = types.uniq types.string;
description = "
Type of the file system.
";
};
options = mkOption {
default = "defaults,relatime";
example = "data=journal";
type = types.string;
merge = pkgs.lib.concatStringsSep ",";
description = "
Option used to mount the file system.
";
};
autocreate = mkOption {
default = false;
type = types.bool;
description = "
Automatically create the mount point defined in
<option>fileSystems.*.mountPoint</option>.
";
};
};
};
system.sbin.mount = mkOption {
internal = true;
default = pkgs.utillinuxng;
description = "
Package containing mount and umount.
";
};
};
###### implementation
config = {
# Add the mount helpers to the system path so that `mount' can find them. # Add the mount helpers to the system path so that `mount' can find them.
environment.systemPackages = [pkgs.ntfs3g pkgs.mount_cifs pkgs.nfsUtils]; environment.systemPackages = [pkgs.ntfs3g pkgs.mount_cifs pkgs.nfsUtils];
jobAttrs.filesystems =
{ startOn = [ "startup" "new-devices" "ip-up" ];
script = task;
task = true;
};
};
} }

View File

@ -1,27 +1,18 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### implementation
let
modprobe = config.system.sbin.modprobe;
in
{ {
services = { ###### implementation
extraJobs = [{
name = "lvm";
job = '' config = {
start on udev
#start on new-devices
script jobAttrs.lvm =
{ startOn = " udev"; # !!! or on new-devices
script =
''
# Load the device mapper. # Load the device mapper.
${modprobe}/sbin/modprobe dm_mod || true ${config.system.sbin.modprobe}/sbin/modprobe dm_mod || true
${pkgs.devicemapper}/sbin/dmsetup mknodes ${pkgs.devicemapper}/sbin/dmsetup mknodes
# Scan for block devices that might contain LVM physical volumes # Scan for block devices that might contain LVM physical volumes
@ -33,9 +24,11 @@ in
${pkgs.lvm2}/sbin/vgchange --available y ${pkgs.lvm2}/sbin/vgchange --available y
initctl emit new-devices initctl emit new-devices
end script
''; '';
}];
task = true;
}; };
};
} }

View File

@ -132,7 +132,6 @@ in
pkgs.wirelesstools pkgs.wirelesstools
]; ];
jobs = pkgs.lib.singleton jobs = pkgs.lib.singleton
{ name = "network-interfaces"; { name = "network-interfaces";

View File

@ -1,4 +1,4 @@
{pkgs, config, ...}: { config, pkgs, ... }:
###### implementation ###### implementation
@ -12,16 +12,11 @@ in
{ {
services = { jobAttrs.swraid =
extraJobs = [{ { startOn = "udev"; # !!! or on "new-devices"
name = "swraid";
job = ''
start on udev
#start on new-devices
script
script =
''
# Load the necessary RAID personalities. # Load the necessary RAID personalities.
# !!! hm, doesn't the kernel load these automatically? # !!! hm, doesn't the kernel load these automatically?
for mod in raid0 raid1 raid5; do for mod in raid0 raid1 raid5; do
@ -35,10 +30,9 @@ in
${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan ${mdadm}/sbin/mdadm --assemble -c ${tempConf} --scan
initctl emit new-devices initctl emit new-devices
end script
''; '';
}];
task = true;
}; };
} }