This feature is available since 1.260
To reliably kill processes spawned by a job during a build, Jenkins contains a bit of native code to list up such processes and kill them. This is tested on several platforms and architectures, but if you find a show-stopper problem because of this, you can disable this feature by setting a Java property named "hudson.util.ProcessTree.disable" to the value "true".
This can be done as a parameter to the "java" binary when starting Jenkins:
java -Dhudson.util.ProcessTree.disable=true -jar jenkins.war
Depending on how you run your container, this can be different. In the distributed build environment, this system property needs to be set on slave JVMs.
Older versions of Hudson (<1.315) used the Java Property hudson.util.ProcessTreeKiller.disable
, but the class ProcessTreeKiller has been depecated since. For compatibility reasons, currently both property names are supported (as of version 1.404).
How it works
The ProcessTreeKiller takes advantage of the fact that by default a new process gets a copy of the environment variables of its spawning/creating process.
It sets a specific environment variable in the process executing the build job. Later, when the user requests to stop the build job's process it gets a list of all processes running on the computer and their environment variables, and looks for the environment variable that it initially set for the build job's process.
Every job with that environment variable in its environment is then terminated.
If your build wants to leave a daemon running behind...
A convenient way to achieve that is to change the environment variable BUILD_ID which Jenkins's ProcessTreeKiller is looking for. This will cause Jenkins to assume that your daemon is not spawned by the Jenkins build. For example:
BUILD_ID=dontKillMe /usr/apache/bin/httpd
In case of Jenkins Pipeline use JENKINS_NODE_COOKIE
instead of BUILD_ID
8 Comments
Unknown User (dcate)
Does this work if there are multiple Hudson Servers installed on the same machine?
Kohsuke Kawaguchi
Yes
Unknown User (chad.lyon@gmail.com)
Could you provide more details about how this works. For example what is the name of the shell environment variable that the job process sets? Also, what signal is sent to the process to kill it (on Unix)?
Suggestion:
It would be nice to be able to configure the disable property through a context param. For example, I run Hudson through Tomcat and I would like to specify my hudson context like so:
BTW, thank you for Hudson
Koushik Prasad
My slave is on linux and I don't see any way to solve this.
I have added the parameter BUILD_ID=dontKillMe both in the job parameters and in the target of my build file.
Is there any plan of fixing this?
Monique Maker
A workaround for the spawned processes killing, since recent Jenkins versions, is to change the value of the JENKINS_NODE_COOKIE environment variable. For more information you can follow to
Revisit use of $JENKINS_SERVER_COOKIE and Launcher.kill and Running a background process in Pipeline job
Sebastián Petrík
Finally managed to keep my Gradle daemon alive (by setting BUILD_ID). Since the last update (2.138.1) the Gradle plugin just starts a new daemon on every build and doesn't keep it which is very frustrating as every build takes +15 seconds. Is this a Jenkins problem or was it alwys lik this?
Denys Digtiar
If Gradle Daemon inherits the environment of the Gradle process starting then it is a candidate for
ProcessTreeKiller
which was introduced in 1.260, hence it's been like this for a while. My understanding is that the build process tree pruning is there to prevent crashing agents with runaway processes created by builds.Sebastián Petrík
Denys Digtiar seems about right, I've read somewhere that using a Gradle Daemon for CI isn't really a good idea, but BUILD_ID set as environment variable works even for all jobs so I'm enjoying my 3 second builds again