2008-12-04 16:48:27 +01:00
|
|
|
{config, pkgs, ...}:
|
2008-11-18 19:00:09 +01:00
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
with pkgs.lib;
|
2008-12-07 13:27:46 +01:00
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
let
|
2009-07-15 13:38:17 +02:00
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
# From a job description, generate an Upstart job file.
|
|
|
|
makeJob = job@{buildHook ? "", ...}:
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
jobText = if job.job != "" then job.job else
|
|
|
|
''
|
2009-07-16 16:51:49 +02:00
|
|
|
# Upstart job `${job.name}'. This is a generated file. Do not edit.
|
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
description "${job.description}"
|
|
|
|
|
2009-07-16 16:51:49 +02:00
|
|
|
${if isList job.startOn then
|
|
|
|
# This is a hack to support or-dependencies on Upstart 0.3.
|
|
|
|
concatMapStrings (x: "start on ${x}\n") job.startOn
|
|
|
|
else if job.startOn != "" then
|
|
|
|
"start on ${job.startOn}"
|
|
|
|
else ""
|
|
|
|
}
|
|
|
|
|
|
|
|
${if job.stopOn != "" then "stop on ${job.stopOn}" else ""}
|
2009-07-15 17:24:11 +02:00
|
|
|
|
|
|
|
${concatMapStrings (n: "env ${n}=${getAttr n job.environment}\n") (attrNames job.environment)}
|
|
|
|
|
|
|
|
${if job.preStart != "" then ''
|
|
|
|
start script
|
|
|
|
${job.preStart}
|
|
|
|
end script
|
|
|
|
'' else ""}
|
|
|
|
|
2009-07-16 16:51:49 +02:00
|
|
|
${if job.script != "" && job.exec != "" then
|
|
|
|
abort "Job ${job.name} has both a `script' and `exec' attribute."
|
|
|
|
else if job.script != "" then
|
|
|
|
''
|
|
|
|
script
|
|
|
|
${job.script}
|
|
|
|
end script
|
|
|
|
''
|
|
|
|
else if job.exec != "" then
|
|
|
|
''
|
|
|
|
exec ${job.exec}
|
|
|
|
''
|
|
|
|
else
|
|
|
|
# Simulate jobs without a main process (which Upstart 0.3
|
|
|
|
# doesn't support) using a semi-infinite sleep.
|
|
|
|
''
|
|
|
|
exec sleep 1e100
|
|
|
|
''
|
|
|
|
}
|
|
|
|
|
|
|
|
${if job.respawn && !job.task then "respawn" else ""}
|
2009-07-16 15:46:49 +02:00
|
|
|
|
|
|
|
${if job.postStop != "" then ''
|
|
|
|
stop script
|
|
|
|
${job.postStop}
|
|
|
|
end script
|
|
|
|
'' else ""}
|
2009-09-04 17:27:52 +02:00
|
|
|
|
|
|
|
${job.extraConfig}
|
2009-07-15 17:24:11 +02:00
|
|
|
'';
|
|
|
|
|
|
|
|
in
|
|
|
|
pkgs.runCommand ("upstart-" + job.name)
|
|
|
|
{ inherit buildHook; inherit jobText; }
|
|
|
|
''
|
|
|
|
eval "$buildHook"
|
|
|
|
ensureDir $out/etc/event.d
|
|
|
|
echo "$jobText" > $out/etc/event.d/${job.name}
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
2009-07-15 14:52:32 +02:00
|
|
|
jobs =
|
|
|
|
[pkgs.upstart] # for the built-in logd job
|
2009-10-05 20:31:27 +02:00
|
|
|
++ (map makeJob (mapAttrsFlatten (name: job: job // { inherit name; } ) config.jobAttrs));
|
2009-05-27 12:32:30 +02:00
|
|
|
|
|
|
|
# Create an etc/event.d directory containing symlinks to the
|
|
|
|
# specified list of Upstart job files.
|
2009-07-15 13:38:17 +02:00
|
|
|
jobsDir = pkgs.runCommand "upstart-jobs" {inherit jobs;}
|
2009-05-27 12:32:30 +02:00
|
|
|
''
|
|
|
|
ensureDir $out/etc/event.d
|
|
|
|
for i in $jobs; do
|
|
|
|
if ln -s $i . ; then
|
|
|
|
if test -d $i; then
|
|
|
|
ln -s $i/etc/event.d/* $out/etc/event.d/
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo Duplicate entry: $i;
|
|
|
|
fi;
|
|
|
|
done
|
2009-05-28 01:30:29 +02:00
|
|
|
''; # */
|
2009-01-02 17:06:41 +01:00
|
|
|
|
2009-10-05 20:31:27 +02:00
|
|
|
listJobOptions = {
|
2009-07-15 15:41:00 +02:00
|
|
|
|
|
|
|
name = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
example = "sshd";
|
|
|
|
description = ''
|
|
|
|
Name of the Upstart job.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
job = mkOption {
|
2009-07-15 17:24:11 +02:00
|
|
|
default = "";
|
2009-07-15 15:41:00 +02:00
|
|
|
type = types.string;
|
|
|
|
example =
|
|
|
|
''
|
2009-07-15 11:06:36 +02:00
|
|
|
description "nc"
|
|
|
|
start on started network-interfaces
|
|
|
|
respawn
|
|
|
|
env PATH=/var/run/current-system/sw/bin
|
|
|
|
exec sh -c "echo 'hello world' | ${pkgs.netcat}/bin/nc -l -p 9000"
|
2009-07-15 15:41:00 +02:00
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
Contents of the Upstart job.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
buildHook = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "true";
|
|
|
|
description = ''
|
|
|
|
Command run while building the Upstart job. Can be used
|
|
|
|
to perform simple regression tests (e.g., the Apache
|
|
|
|
Upstart job uses it to check the syntax of the generated
|
|
|
|
<filename>httpd.conf</filename>.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
description = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "(no description given)";
|
|
|
|
description = ''
|
|
|
|
A short description of this job.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
startOn = mkOption {
|
2009-07-16 16:51:49 +02:00
|
|
|
# !!! Re-enable this once we're on Upstart >= 0.6.
|
|
|
|
#type = types.string;
|
2009-07-15 17:24:11 +02:00
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
The Upstart event that triggers this job to be started.
|
|
|
|
If empty, the job will not start automatically.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
stopOn = mkOption {
|
|
|
|
type = types.string;
|
2009-07-16 15:55:11 +02:00
|
|
|
default = "shutdown";
|
2009-07-15 17:24:11 +02:00
|
|
|
description = ''
|
|
|
|
The Upstart event that triggers this job to be stopped.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
preStart = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Shell commands executed before the job is started
|
2009-07-16 15:46:49 +02:00
|
|
|
(i.e. before the job's main process is started).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
postStop = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Shell commands executed after the job has stopped
|
|
|
|
(i.e. after the job's main process has terminated).
|
2009-07-15 17:24:11 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
exec = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
2009-07-16 15:46:49 +02:00
|
|
|
Command to start the job's main process. If empty, the
|
|
|
|
job has no main process, but can still have pre/post-start
|
|
|
|
and pre/post-stop scripts, and is considered "running"
|
|
|
|
until it is stopped.
|
2009-07-15 17:24:11 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-16 16:51:49 +02:00
|
|
|
script = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "";
|
|
|
|
description = ''
|
|
|
|
Shell commands executed as the job's main process. Can be
|
|
|
|
specified instead of the <varname>exec</varname> attribute.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 17:53:39 +02:00
|
|
|
respawn = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = ''
|
|
|
|
Whether to restart the job automatically if its process
|
|
|
|
ends unexpectedly.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-16 16:51:49 +02:00
|
|
|
task = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Whether this job is a task rather than a service. Tasks
|
|
|
|
are executed only once, while services are restarted when
|
|
|
|
they exit.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 17:24:11 +02:00
|
|
|
environment = mkOption {
|
|
|
|
type = types.attrs;
|
|
|
|
default = {};
|
|
|
|
example = { PATH = "/foo/bar/bin"; LANG = "nl_NL.UTF-8"; };
|
|
|
|
description = ''
|
|
|
|
Environment variables passed to the job's processes.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-09-04 17:27:52 +02:00
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.string;
|
|
|
|
default = "";
|
|
|
|
example = "limit nofile 4096 4096";
|
|
|
|
description = ''
|
|
|
|
Additional Upstart stanzas not otherwise supported.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2009-07-15 15:41:00 +02:00
|
|
|
};
|
2009-10-05 20:31:27 +02:00
|
|
|
|
|
|
|
attrJobOptions = builtins.removeAttrs listJobOptions ["name"];
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
###### interface
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
|
|
|
jobAttrs = mkOption {
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
This option defines the system jobs started and managed by the
|
|
|
|
Upstart daemon.
|
|
|
|
|
|
|
|
It's filled by config.jobs by now. A warning is print.
|
|
|
|
|
|
|
|
You can overwrite settings easily. Example:
|
|
|
|
|
|
|
|
config.jobAttrs.sshd.startOn = "never";
|
|
|
|
'';
|
|
|
|
|
|
|
|
options = attrJobOptions;
|
|
|
|
type = types.attrsOf types.optionSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
jobs = mkOption {
|
|
|
|
default = [];
|
|
|
|
description = ''
|
|
|
|
See jobAttrs
|
|
|
|
'';
|
|
|
|
|
|
|
|
type = types.list types.optionSet;
|
|
|
|
|
|
|
|
options = listJobOptions;
|
2009-07-15 15:41:00 +02:00
|
|
|
|
2009-07-15 13:19:11 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
services.extraJobs = mkOption {
|
|
|
|
default = [];
|
|
|
|
description = ''
|
|
|
|
Obsolete - don't use.
|
2009-07-15 11:06:36 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
tests.upstartJobs = mkOption {
|
|
|
|
internal = true;
|
|
|
|
default = {};
|
|
|
|
description = ''
|
|
|
|
Make it easier to build individual Upstart jobs. (e.g.,
|
|
|
|
<command>nix-build /etc/nixos/nixos -A
|
|
|
|
tests.upstartJobs.xserver</command>).
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2008-11-18 19:00:09 +01:00
|
|
|
};
|
|
|
|
|
2009-07-15 11:06:36 +02:00
|
|
|
|
|
|
|
###### implementation
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
2009-10-05 20:31:27 +02:00
|
|
|
# add jobs of list style. If there are some print deprecation message
|
|
|
|
jobAttrs =
|
|
|
|
let deprecatedJobDefs = config.jobs ++ config.services.extraJobs;
|
|
|
|
jobList = concatStringsSep ", " (map (j: j.name) deprecatedJobDefs);
|
|
|
|
jobs = if deprecatedJobDefs != [] then
|
|
|
|
builtins.trace "Make the following jobs use jobAttrs please. Using jobs is depreceated: ${jobList}"
|
|
|
|
deprecatedJobDefs
|
|
|
|
else deprecatedJobDefs;
|
|
|
|
in builtins.listToAttrs (map (job: { inherit (job) name; value = builtins.removeAttrs job ["name"]; }) jobs);
|
|
|
|
|
2009-07-15 11:06:36 +02:00
|
|
|
environment.etc =
|
|
|
|
[ { # The Upstart events defined above.
|
2009-07-15 13:38:17 +02:00
|
|
|
source = "${jobsDir}/etc/event.d";
|
2009-07-15 11:06:36 +02:00
|
|
|
target = "event.d";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
|
|
|
# see test/test-upstart-job.sh (!!! check whether this still works)
|
|
|
|
tests.upstartJobs = { recurseForDerivations = true; } //
|
2008-11-18 19:00:09 +01:00
|
|
|
builtins.listToAttrs (map (job:
|
|
|
|
{ name = if job ? jobName then job.jobName else job.name; value = job; }
|
|
|
|
) jobs);
|
2009-07-15 11:06:36 +02:00
|
|
|
|
2008-11-18 19:00:09 +01:00
|
|
|
};
|
2009-07-15 11:06:36 +02:00
|
|
|
|
2009-01-02 17:07:21 +01:00
|
|
|
}
|