I have a Python script, part of a test system that calls many third party tools/processes on multiple [Windows] machines, and hence has been designed to clean up comprehensively/carefully when aborted with CTRL-C; the clean-up can take many seconds, depending on what's going on. This clean-up process works fine from a [Windows] command prompt.
I run that Python script from [a scripted pipeline] Jenkinsfile, using return_value = bat("python my_script.py params", returnStatus: true)
, which also works fine.
However I need to be able to perform the abort/clean-up during a Jenkins [v2.263.4] run, i.e. when someone presses the little red X, and that bit I can't fathom. I understand that Jenkins sends SIGTERM
when the abort button is pressed so I am trapping that in my_script.py
:
SAVED_SIGTERM_HANDLER = signal(SIGTERM, sigterm_handler)
...and running the processes I would normally call from a KeyboardInterrupt
in sigterm_handler()
as well, but they aren't being called. I understand that the IO stream to the Jenkins console stops the moment the abort button is pressed; I can see that the clean-up functions aren't being called by looking at the behaviour of my script(s) from the "other side": it appears as though my_script.py
is simply stopping dead, all connections from it drop the moment the abort button is pressed, there is no clean-up.
Can anyone suggest a way of making the abort button in Jenkins give my bat()
ed Python script time to clean-up? Or am I just doing something wrong? Or is there some other approach to this within Jenkins that I'm missing?
After much figuring out, and kudos to our tools people who found the critical "cookie" implementation detail in Jenkins, the workaround to take control of the abort process [on Windows] is as follows:
JENKINS_SERVER_COOKIE="ignore"
added to it; Jenkins uses this flag to find the processes it has launched in order to kill them, so you must set this "cookie" to "ignore" to stop Jenkins killing (b),try()
/catch()
/finally()
and call (c) from the finally()
, hence ensuring that the Jenkins pipeline only finishes when (b) has terminated (you might want to add a guard timer for safety).Quite a thing, and all for the lack of what would be a relatively simple API in Jenkins.