Search code examples
bashdockersignalsstardog

How do I create a PID trap for multiple commands separated by &&


I'm running Stardog 4.0 in an Ubuntu 15.04 container with open jdk8 which runs fine. I want to handle gracefully shutting down stardog using a trap.

To execute stardog in a container so that it continues to run I've been using the following which works well

$SBIN/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done

Without the following the container will run for a few seconds and stop

&& (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done

However this leads to multiple PID's within the container

root         1  0.0  0.0  18384  3236 ?        Ss   14:04   0:02 /bin/bash /stardog_binaries/startup.sh
root        45  0.1  4.9 4619052 406940 ?      Sl   14:04   0:10 java -Xms2g -Xmx2g -XX:MaxDirectMemorySize=4g -XX:SoftRefLRUPolicyMSPerMB=1 -XX:+UseParallelOldGC -XX:+UseCompressedOops -Djavax.xml.datatype.DatatypeFactory=org.apache.xerc
root        97  0.0  0.0   4412   740 ?        S    14:04   0:00 tail -f /storage/stardog.log
root     12108  0.2  0.0  18184  3100 ?        Ss   15:44   0:00 bash
root     12122  0.0  0.0   4376   784 ?        S    15:44   0:00 sleep 1

And the following trap does not work to shutdown stardog when the container is shutting down

trap 'kill -TERM $PID' TERM INT
$SBIN/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done
PID=$!
wait $PID
trap - TERM INT
wait $PID
EXIT_STATUS=$?

So my question is how do I properly trap the $SBIN/bin/stardog-admin server start such that when the container shuts downs, stardog gracefully exits.

Regards Conteh


Solution

  • In the end I created a runstardog.sh script in the container.

    set -e
    function shutdown() {        
     $STARDOG_BINARIES/bin/stardog-admin server stop  -p xxx -u admin    
    }
    
    $STARDOG_BINARIES/bin/stardog-admin server start && (tail -f /storage/stardog.log &) && while (pidof java > /dev/null); do sleep 1; done
    
    trap "{ shutdown }" EXIT
    exit 0
    

    Which is executed by a startup.sh script that contains the following trap

    trap 'kill -TERM $PID' TERM INT
    $STARDOG_BINARIES/runstardog.sh &
    PID=$!
    wait $PID
    trap - TERM INT
    wait $PID
    EXIT_STATUS=$?
    

    and then when I want to stop the server I call stop.sh on the server hosting the container which identifies the CID for the stardog container, shuts down stardog using docker exec and the stops and deletes the container.

    replace="\1"
    find="([a-z0-9]{12})\s+platform_stardog.*"
    CID=$( docker ps | tail --lines=+2 | sed "/platform_stardog/!d"  | perl -lpe  "s@$find@$replace@g"  )
    
    if [ -z "$CID" ]; 
    then
        echo "No existing container named platform_stardog was found"
    else
        echo "docker exec  /stardog_binaries/stopstardog.sh in platform_stardog Container $CID:"
        docker exec ${CID} /stardog_binaries/stopstardog.sh
        echo "stop and delete docker container."
        /usr/local/bin/docker-compose -p platform -f docker-compose.yml stop -t 30 stardog && /usr/local/bin/docker-compose -p platform -f docker-compose.yml rm --force -v stardog
    fi
    

    I get confirmation that this works due to stardog's output ' Stardog server successfully received the shutdown request' and that the shutdown process does not take long. It used to hang for the 30 seconds specified via the docker compose stop -t 30

    Thanks @VonC I'll try that method next.