Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force kill fails to kill the process group in exec mode #1666

Closed
simonellefsen opened this issue Nov 14, 2022 · 1 comment · Fixed by #1668
Closed

Force kill fails to kill the process group in exec mode #1666

simonellefsen opened this issue Nov 14, 2022 · 1 comment · Fixed by #1668
Labels
Milestone

Comments

@simonellefsen
Copy link

Consul Template version

As far as I can tell starting from version 0.27.0+

Configuration

No special configuration

Command

./consul-template_0.29.5 -log-level=trace -template "/tmp/config.ctmpl:/tmp/server.conf" -exec "IGNORE_SIGNALS=true python3 -u ./program.py"
#!/usr/bin/env python3
"""
Simple python example for testing envconsul/consul-template
"""

from typing import Any
import logging

import os
import sys
import time
import signal

logging.basicConfig(
    format="%(asctime)s [%(levelname)s] %(message)s", level=logging.DEBUG
)


def handler(signum: int, _frame: Any) -> None:
    logging.info("Signal handler called with signal %d", signum)
    if "IGNORE_SIGNALS" in os.environ:
        logging.info("Ignoring signal %d", signum)
        return
    sys.exit(0)


def main() -> None:
    logging.info("Program started")
    signal.signal(signal.SIGHUP, handler)
    signal.signal(signal.SIGINT, handler)
    signal.signal(signal.SIGTERM, handler)
    # loop forever
    logging.info("Looping...")
    while True:
        logging.info("Dumping _VAULT and _CONSUL environment variables")
        for _e in os.environ:
            if (
                (_e[:6] == "_VAULT" or _e[:7] == "_CONSUL")
                and not _e.endswith("_PASSWORD")
                and not _e.endswith("_SECRET_KEY")
                and not _e.endswith("_SECURITY_TOKEN")
            ):
                logging.info("%s=%s", _e, os.environ[_e])
        time.sleep(3600)
    # should not happen
    logging.info("Loop exit")
    sys.exit(1)


if __name__ == "__main__":
    main()

Debug output

https://gist.github.com/simonellefsen/206dd8476b7d0a0670fa79fdbf03a281

   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
 737303  777229  777229  737303 pts/0     777229 Sl+   5004   0:00  \_ ./consul-template_0.29.5 -log-level=trace -template /tmp/config.ctmpl:/tmp/server.conf -exec IGNORE_SIGNALS=true python3 -u ./program.py
 777229  777237  777237  737303 pts/0     777229 S     5004   0:00      \_ sh -c IGNORE_SIGNALS=true python3 -u ./program.py
 777237  777238  777237  737303 pts/0     777229 S     5004   0:00          \_ python3 -u ./program.py

And after "shutdown" the application program is still running

   PPID     PID    PGID     SID TTY        TPGID STAT   UID   TIME COMMAND
      1  777238  777237  737303 pts/0     737303 S     5004   0:00 python3 -u ./program.py

Expected behavior

Expect the whole process group to be force killed.

Actual behavior

Force kill (SIGKILL) only kills the spawned subprocess shell and not the whole process group

So if I look at consul-template code

if c.cmd != nil && c.cmd.Process != nil {
c.cmd.Process.Kill()
}

It very much looks like the force kill signal (SIGKILL) is not sent to the process group

But the default kill signal (SIGTERM) is sent to the process group

if c.setpgid {
// kill takes negative pid to indicate that you want to use gpid
pid = -(pid)
}
which fits with the log output from the application

References

@eikenb
Copy link
Contributor

eikenb commented Nov 14, 2022

Discovered in envconsul... hashicorp/envconsul#317

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants