skip to Main Content

I have the following ECS container definition

ContainerDefinitions:
        - Name: myfluentd
          Essential: true
          Image: !Ref DockerImage
          MountPoints:
            - SourceVolume: efs-volume
              ContainerPath: '/fluentd/buffers'
              ReadOnly: false
          PortMappings:
            - ContainerPort: 24224
              HostPort: 24224
              Protocol: tcp
          EntryPoint:
            - "/var/lib/twistlock/defender.sh"
            - "defender"
            - "entrypoint"
            - "tini"
            - "--"
            - "/bin/entrypoint.sh"
          Command:
            - fluentd
          VolumesFrom:
            - ReadOnly: false
              SourceContainer: "TwistlockDefender"

The ENTRYPOINT is

["/var/lib/twistlock/fargate/fargate_defender.sh","fargate","entrypoint","tini","--","/bin/entrypoint.sh"]

and the contents of entrypoint.sh

#!/bin/sh

#source vars if file exists
DEFAULT=/etc/default/fluentd

if [ -r $DEFAULT ]; then
    set -o allexport
    . $DEFAULT
    set +o allexport
fi

# If the user has supplied only arguments append them to `fluentd` command
if [ "${1#-}" != "$1" ]; then
    set -- fluentd "$@"
fi

# If user does not supply config file or plugins, use the default
if [ "$1" = "fluentd" ]; then
    if ! echo $@ | grep ' -c' ; then
       set -- "$@" -c /fluentd/etc/${FLUENTD_CONF}
    fi

    if ! echo $@ | grep ' -p' ; then
       set -- "$@" -p /fluentd/plugins
    fi
fi

. /bin/env.sh

task_cleanup() {
    echo "Deleting files"
    rm -rf /tmp/*
    exit
}
trap task_cleanup SIGTERM SIGINT

exec "$@"

When I stop a ECS task it issues the SIGTERM to the container and I expect it to executed the task_cleanup(), however the signal is not caught.

I logged into the container to check the processes

PID   USER     TIME  COMMAND
    1 fluent    0:00 sh /var/lib/twistlock/defender.sh defender entrypoint tini -- /bin/entrypoint.sh fluentd
    7 fluent    0:00 /var/lib/twistlock/defender defender entrypoint tini -- /bin/entrypoint.sh fluentd
   16 root      0:00 /managed-agents/execute-command/amazon-ssm-agent
   22 fluent    0:00 /sbin/tini -- /bin/entrypoint.sh fluentd
   29 fluent    0:02 {fluentd} /usr/bin/ruby /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins
   72 root      0:00 /managed-agents/execute-command/ssm-agent-worker
   90 fluent    1:06 /usr/bin/ruby -Eascii-8bit:ascii-8bit /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins --under-supervisor
  546 root      0:00 /managed-agents/execute-command/ssm-session-worker ecs-execute-command-03931001c6df08625
  556 root      0:00 /bin/bash
  870 root      0:00 ps aux 

What am I missing? why is the signal not getting trapped?

UPDATE: The ENTRYPOINT kicks off 2 containers and I think the signal is only sent to the first container – when I removed the first container, I was able to see the cleanup working. Any thoughts how to handle this?

2

Answers


  1. Per the POSIX documentation for exec (bolding mine):

    If exec is specified with command, it shall replace the shell with command without creating a new process. …

    Your shell process and the signal handler you created with trap no longer exists once you call exec "$@".

    This will probably do what you want, but it’s totally untested and I haven’t analyzed what the string "$@" that you’ve constructed:

       .
       .
       .
    task_cleanup() {
        echo "Deleting files"
        rm -rf /tmp/*
    }
    trap task_cleanup SIGTERM SIGINT
    
    # background the task
    "$@" &
    pid=$!
    
    wait $pid
    
    kill $pid
    
    exit
    

    Instead of replacing the shell with the command held in "$@", this would run the command as a child process of the shell.

    Login or Signup to reply.
  2. Save following script in test.sh

    #!/usr/bin/env bash
      
    task_cleanup() {
        echo "Deleting files"
    }
    trap task_cleanup SIGTERM
    
    "$@"
    

    and run it with :

    bash test.sh sleep 60
    

    Now run ps -ef|grep "bash test.sh sleep 60" (in another bash session) to grab the PID, then run

    kill -TERM PID
    

    The process will catch the signal TERM but only run task_cleanup AFTER sleep 60 finishes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search