blob: 1bb6c93ac58e0afb1ade3b9daae14e1b713c0d20 [file] [log] [blame]
Below is a summary of the code style conventions for Chromium OS
upstart jobs. Please use this style for all new upstart jobs.
Due to history, not all jobs in this package conform to style; you
are encouraged to update files to conform when you make changes.
== Whitespace conventions:
* Indentation is in 2 column increments.
* Indent with spaces, not tabs.
* Lines should not exceed 72 columns; lines must not exceed 80
columns.
* Long lines may be continued with a '\' at end of line. The
first continuation line must be indented at least 2 columns;
more may be used to align the text with some significant element
on the line being continued. Subsequent continuation lines
should be indented to align with the first continuation line.
== Breaking the rules:
"A foolish consistency is the hobgoblin of little minds"
Ralph Waldo Emerson
"The young man knows the rules, but the old man knows the exceptions."
Oliver Wendell Holmes
Code style guidelines exist to create consistency in the source
code, and to avoid constructs that lead to bugs. If you think the
style guide is interfering with writing good code, you can break the
rules provided:
1) You know what you're doing.
2) You've got a good reason for doing it.
3) You provide a clear comment explaining why it's necessary.
== Standard template:
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
description "<description of job>"
author "chromium-os-dev@chromium.org"
# Optional comment describing the job. Explain anything
# non-obvious that's not explained in the description. Explain
# any non-obvious dependencies in the start and stop conditions,
# and justify 'task' if necessary. If everything you might say
# is covered in 'description', 'start on', 'stop on', etc., leave
# this out.
start on ... # optional
stop on ... # optional; typically not with 'task'
respawn # optional; typically not with 'task'
task # optional; typically not with 'stop' or 'respawn'
# other upstart stanzas as needed
pre-start ... # optional
post-start ... # optional
expect ... # optional
exec ... # optional, can't use this with "script"
script ... # optional, can't use this with "exec"
pre-stop ... # optional
post-stop ... # optional
== Notes about the use of 'task'
The 'task' keyword does not mean "this job should not respawn"; it
means that when the job starts, other jobs may be forced to wait for
its completion. In particular:
* If a task starts because of a 'start on starting x' clause, the
'x' job's pre-start, post-start, and main commands will wait for
the task to terminate.
* If a task starts because of a 'start on stopping x' clause, the
'x' job's post-stop commands will wait for the task to
terminate.
* If a task is started by 'initctl emit', the 'initctl' command
will wait for the task to terminate.
Only use 'task' if the task's start conditions require one of these
delays (e.g. to prevent a race condition). If you use 'task', the
reason should typically be explained in the job's descriptive
comments.
In general, 'task' should not be used with either 'stop on' or
'respawn'.
== Format of 'script' and 'exec' commands:
If the command for 'exec' or 'script' involves compound shell
statements, such as a pipe, 'if', or 'for', use 'script'; otherwise,
use 'exec'.
For a job that uses 'respawn', a 'pre-start script' with a main
process invoked via 'exec' is preferable to a main process invoked
with 'script' without 'pre-start'. If your job uses 'respawn' but
the main process must be a script, then
* The final command in the script should be invoked with 'exec'.
* The job should not use 'expect fork' or 'expect daemon'.
A 'script' stanza (including for pre-start, pre-stop, etc.) consists
of multiple shell commands, laid out as with this template:
script
# commands here, indented
end script
The commands in 'script' and 'exec' stanzas must conform to
Chromium OS shell style conventions, most notably:
* Use only POSIX standard features. Note that the shell
interpreter is 'dash', not 'bash'.
* Use $() for command substitution, not ``
* Format compound statements such as 'if', 'for', and 'while'
along these lines:
if [ -f "${testfile}" ] ; then
# ...
fi
* In general, don't use a fully qualified path name for a command
located in any of the following directories:
/bin /sbin /usr/bin /usr/sbin
== Conventions for logging messages
Jobs can (should) log significant events via syslog for debug or
diagnosis. Use this idiom for messages:
logger -t "${UPSTART_JOB}" "<your message goes here>"