| #!/usr/bin/env python |
| # -*- encoding: utf-8 -*- |
| |
| # Copyright 2016 Twitter. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| ''' killexecutorhandler.py ''' |
| import logging |
| import os |
| import signal |
| import urlparse |
| import subprocess |
| import tornado.web |
| |
| from tornado.options import options |
| |
| class KillExecutorHandler(tornado.web.RequestHandler): |
| """ |
| Responsible for killing heron-executor process. |
| """ |
| @tornado.web.asynchronous |
| def post(self): |
| """ post method """ |
| def status_finish(ret): |
| self.set_status(ret) |
| self.finish() |
| |
| def kill_parent(): |
| status_finish(200) |
| try: |
| logger.info("Print stmgr backtrace to ./stmgr.bt") |
| cmd = 'timeout 3 gdb -batch -ex "thread apply all bt" -p `cat stmgr-1.pid` 2&>1 > stmgr.bt' |
| subprocess.call(cmd, shell=True) |
| except Exception: |
| logger.warning("Exception: ") |
| logger.info("Killing parent executor") |
| os.killpg(os.getppid(), signal.SIGTERM) |
| |
| logger = logging.getLogger(__file__) |
| logger.info("Received 'Killing process' request") |
| data = dict(urlparse.parse_qsl(self.request.body)) |
| |
| # check shared secret |
| sharedSecret = data.get('secret') |
| if sharedSecret != options.secret: |
| status_finish(403) |
| return |
| |
| instanceId = data.get('instance_id_to_restart') |
| if instanceId: |
| filepath = instanceId + '.pid' |
| if os.path.isfile(filepath): # instance_id found |
| if instanceId.startswith('heron-executor-'): # kill heron-executor |
| kill_parent() |
| else: # kill other normal instance |
| fh = open(filepath) |
| firstLine = int(fh.readline()) |
| fh.close() |
| logger.info("Killing process " + instanceId + " " + str(firstLine)) |
| os.kill(firstLine, signal.SIGTERM) |
| status_finish(200) |
| else: # instance_id not found |
| logger.info(filepath + " not found") |
| status_finish(422) |
| else: # instance_id not given, which means kill the container |
| kill_parent() |