How to terminate psql process inside Jenkins job with SIGINT instead of SIGTERM when aborted?

Viewed 458

I have a Jenkins job that fires a long-running SQL function in a PostgreSQL database using a psql command in a shell (bash) script. Sometimes the computation needs to be terminated to unblock other queries on the server. But if the job is manually aborted, the SQL function stays running (within a postgresql process) on the server although the psql command gets terminated.

I found out that psql needs to be aborted by SIGINT to cancel the query properly, but Jenkins apparently sends SIGTERM to all processes spawned in within the job execution.

I tried trapping the TERM signal in the job script and sending SIGINT to the psql that was run on background, but psql still received SIGTERM first and finished without stopping the query.

According to this Jenkins kills the whole process group of the script, but starting psql in a separate process group (set -m) also doesn't help.

Is there any way to stop the psql query gracefully upon Jenkins job abort?

1 Answers

I ended up using this workaround. Add trap SIGTERM signal for the psql process and kill the running process with normal SIGTERM in the cleanup procedure:

function clean() {
    echo "Interrupted: psql #$1" >&2
    kill -SIGINT $1
    wait $1
    echo "psql ended" >&2
}

psql -c 'select pg_sleep(10)' &
pid=$!

trap "clean $pid" SIGTERM

Then run the script through SSH Publisher build step (Publish Over SSH Plugin). Two checkboxes must be set for the job to work correctly:

  1. Exec in pty in Transfers block -> Advanced button
  2. Fail the build if an error occurs in Server block -> Advanced button
Related