Runtime Environment¶
bpm is explicit about the interface that it provides to your job. If there is anything in this specification which is unclear or non-specific then please let us know so that we can be explicit about the interface and guarantees provided.
Lifecycle¶
Your process is started and has an unlimited amount of time to start up. If present, a bpm pre-start script can run before your process' pre-start and start. Bpm's pre-start script must complete in within 30 seconds to avoid a monit timeout. A job's pre-start script is not bound by this timeout. You should use a post-start script and a health check if you want your job to only say it has completed deploying after it has started up. You do not need to manage any PID files yourself.
On shutdown your job will receive a SIGTERM
.
Starting in version 1.1.14
, you may choose to have your job receive a SIGINT
instead (see shutdown_signal).
You then have 20 seconds to shutdown your application before it will be sent SIGQUIT
to dump the stack
(this is default behavior in the Go and Java runtimes) before being forcibly
terminated.
If you require longer than this then you should use a drain script for your server. The drain script should put your server in such a state that it can shutdown within 15 seconds. It is acceptable and supported to terminate your process while running the drain script. However, if you do terminate the process then you should also delete the PID file.
Zombie Processes and Forwarding Signals¶
bpm will run an init
process which will start the process your configuration
file. This init
process will reap any zombie processes and forward signals
to your process.
Older versions of bpm did not do this and so we suggested that people use bash-c
to start their process which would reap zombie processes. Unfortunately
this would not forward signals. You can now remove this workaround.
Environment Variables¶
Name | Value |
---|---|
TMPDIR | /var/vcap/data/JOB/tmp |
Logging¶
Your process should write logs to standard output and standard error file
descriptors. This data will be written to
/var/vcap/sys/log/JOB/PROCESS.stdout.log
and
/var/vcap/sys/log/JOB/PROCESS.stderr.log
respectively.
Any other files which are written to /var/vcap/sys/log/JOB
inside the
container will be written to /var/vcap/sys/log/JOB
in the host system.
Resource Limits¶
bpm can enforce various resource limits on your processes. There are currently 3 different types: memory, open files, and processes.
Memory¶
If your process tries to allocate more memory that your configuration allows then it will be immediately killed by the OOM killer. This setting is more useful for agent jobs which do not use more memory under user load and do not want to affect the more important user-facing processes.
Open Files¶
The open files setting sets a limit on the number of open files (including
network connections) which your job is allowed to have open at once. This is
equivalent to setting ulimit -n
for your process.
Processes¶
This setting places a limit on the number of PIDs which your process is allowed to create. This is to protect against fork-bombs and other resource exhaustion mistakes or attacks. Threads also count towards this limit as they are also given PIDs.
Storing Data¶
Temporary Files¶
Applications may store temporary files in either /tmp
or
/var/vcap/data/JOB/tmp
(as per the BOSH recommendation). Both paths,
and /var/tmp
are mapped onto the same host volume
(/var/vcap/data/JOB/tmp
) and changes made to one will instantly appear
in the other.
bpm will set the TMPDIR
environment variable when executing your job to one
of the paths listed above. This environment variable is respected by the
majority of in-use standard libraries used by Cloud Foundry.
Note: Per the BOSH team's guidance the temporary filesystem is not mounted as
tmpfs
.
Ephemeral Data¶
You should store ephemeral data in /var/vcap/data/JOB
. There are no
guarantees that this data will be present in a different invocation of your
job. The lifecycle of this data is tied with the underlying BOSH stemcell.
This storage area is useful for cached data that can be re-created by other means when necessary.
This storage area is shared between all processes in your job. It is your responsibility to make sure that the data saved by each of your job's processes does not collide.
Persistent Data¶
When the path /var/vcap/store
exists bpm will mount the path
/var/vcap/store/JOB
into the job filesystem. As with
/var/vcap/data/JOB
bpm will create the leaf directory if it does not
exist.
NOTE: Because persistent data access defaults to
/var/vcap/store/JOB
, job name changes will cause persistent data to no longer be accessible. When changing the name of a job the BOSHpre-start
script should idempotently move the persistent data from/var/vcap/store/OLD-JOB
to/var/vcap/store/NEW-JOB
.
Shared Data¶
Note: This feature has been added to enable support for older jobs which use the file system to communicate with other jobs. It is preferable in nearly all cases to use the network to communicate across job boundaries. Using the network reduces scheduling constraints such that a job can be un-collocated and allows more modern access control (key rotation, etc.) of the information being transferred between your jobs.
If your job configuration lists shared volumes (additional_volumes:
key) then these
paths will be created if they do not exist before being mounted into the job
filesystem. These volumes will be mounted read-write. All collocated jobs which
list a particular volume path will be given a volume they can all share.
Only volume paths inside the /var/vcap/data
, and (when present) the
/var/vcap/store
directories are currently permitted. Specifying paths which
are not inside this directory will cause the job to fail to start.
monit
Workarounds¶
There are various monit
quirks that bpm attempts to hide or smooth over.
Instant Restart¶
If an operator runs monit stop JOB && monit start JOB
then monit
will wait
until the monitored process has completely stopped and the stop program
listed in the configuration has completely finished before attempting to start
the job again. This is unsurprising behavior.
Unfortunately monit restart
does not wait until the existing
job has stopped before starting the same job again. As soon as the existing job
has removed its PID file monit
forks and starts the new process. This
behavior is unexpected, subtle, and full of race conditions. A considerable
number of BOSH releases are unknowingly suffering from bugs caused by this.
bpm enforces its own locking around process operations to avoid these race
conditions. It is completely safe (from a correctness perspective, you may
still break your service) to run monit restart
on a job which uses bpm.
Execution Failed¶
In some cases Monit reports the process as execution failed when the process is actually healthy. There is a known race condition that can occur in certain unavoidable circumstances. This same failure will also appear if bpm's pre-start script exceeds monit's timeout when executing. It is recommended to move time consuming logic from bpm's pre-start to the job's pre-start script.