You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/06/12 12:16:26 UTC
[2/2] ambari git commit: AMBARI-11717. Ambari-agent died when trying
to auto restart itself (dlysnichenko)
AMBARI-11717. Ambari-agent died when trying to auto restart itself (dlysnichenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/62c8b703
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/62c8b703
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/62c8b703
Branch: refs/heads/branch-2.1
Commit: 62c8b7034c46645ca991c43fd8978a56d065d521
Parents: a3a626c
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Fri Jun 12 13:15:13 2015 +0300
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Fri Jun 12 13:16:06 2015 +0300
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 5 +-
.../src/main/python/ambari_agent/Controller.py | 4 +-
.../src/main/python/ambari_agent/ExitHelper.py | 79 ++++++++++++++++++++
.../ambari_agent/apscheduler/threadpool.py | 4 +-
.../src/main/python/ambari_agent/main.py | 2 +
.../test/python/ambari_agent/TestController.py | 9 ++-
.../src/test/python/ambari_agent/TestMain.py | 7 +-
7 files changed, 96 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index 5d26227..c41397d 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -26,7 +26,6 @@ import logging
import os
import sys
import time
-import atexit
from apscheduler.scheduler import Scheduler
from alerts.collector import AlertCollector
@@ -34,7 +33,7 @@ from alerts.metric_alert import MetricAlert
from alerts.port_alert import PortAlert
from alerts.script_alert import ScriptAlert
from alerts.web_alert import WebAlert
-
+from ambari_agent.ExitHelper import ExitHelper
logger = logging.getLogger(__name__)
class AlertSchedulerHandler():
@@ -72,7 +71,7 @@ class AlertSchedulerHandler():
self.config = config
# register python exit handler
- atexit.register(self.exit_handler)
+ ExitHelper().register(self.exit_handler)
def exit_handler(self):
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index 4e5de6c..572768a 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -44,7 +44,7 @@ from ambari_agent.AlertSchedulerHandler import AlertSchedulerHandler
from ambari_agent.ClusterConfiguration import ClusterConfiguration
from ambari_agent.RecoveryManager import RecoveryManager
from ambari_agent.HeartbeatHandlers import HeartbeatStopHandlers, bind_signal_handlers
-
+from ambari_agent.ExitHelper import ExitHelper
logger = logging.getLogger(__name__)
AGENT_AUTO_RESTART_EXIT_CODE = 77
@@ -384,7 +384,7 @@ class Controller(threading.Thread):
self.heartbeatWithServer()
def restartAgent(self):
- sys.exit(AGENT_AUTO_RESTART_EXIT_CODE)
+ ExitHelper().exit(AGENT_AUTO_RESTART_EXIT_CODE)
def sendRequest(self, url, data):
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/main/python/ambari_agent/ExitHelper.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/ExitHelper.py b/ambari-agent/src/main/python/ambari_agent/ExitHelper.py
new file mode 100644
index 0000000..06dfadb
--- /dev/null
+++ b/ambari-agent/src/main/python/ambari_agent/ExitHelper.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+'''
+
+import os
+import logging
+import atexit
+
+logger = logging.getLogger(__name__)
+
+__all__ = ["ExitHelper"]
+
+class _singleton(type):
+ _instances = {}
+
+ def __call__(cls, *args, **kwargs):
+ if cls not in cls._instances:
+ cls._instances[cls] = super(_singleton, cls).__call__(*args, **kwargs)
+ return cls._instances[cls]
+
+
+class ExitHelper(object):
+ """
+ Class to cleanup resources before exiting. Replacement for atexit module. sys.exit(code) works only from threads and
+ os._exit(code) will ignore atexit and cleanup will be ignored.
+ """
+ __metaclass__ = _singleton
+
+ def __init__(self):
+ self.exit_functions = []
+ self.exit_functions_executed = False
+ atexit.register(self.execute_cleanup)
+
+ def execute_cleanup(self):
+ if self.exit_functions_executed:
+ return
+ logger.info("Performing cleanup before exiting...")
+ while self.exit_functions:
+ func, args, kwargs = self.exit_functions.pop()
+ try:
+ func(*args, **kwargs)
+ except:
+ pass
+ self.exit_functions_executed = True
+
+ def register(self, func, *args, **kwargs):
+ self.exit_functions.append((func, args, kwargs))
+
+ def exit(self, code):
+ self.execute_cleanup()
+ os._exit(code)
+
+
+if __name__ == '__main__':
+ def func1():
+ print "1"
+
+ def func2():
+ print "2"
+
+ ExitHelper().register(func1)
+ ExitHelper().register(func2)
+ ExitHelper().exit(3)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/main/python/ambari_agent/apscheduler/threadpool.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/apscheduler/threadpool.py b/ambari-agent/src/main/python/ambari_agent/apscheduler/threadpool.py
index 8ec47da..6cd7ce2 100644
--- a/ambari-agent/src/main/python/ambari_agent/apscheduler/threadpool.py
+++ b/ambari-agent/src/main/python/ambari_agent/apscheduler/threadpool.py
@@ -7,7 +7,7 @@ ThreadPool!
from threading import Thread, Lock, currentThread
from weakref import ref
import logging
-import atexit
+from ambari_agent.ExitHelper import ExitHelper
try:
from queue import Queue, Empty
@@ -27,7 +27,7 @@ def _shutdown_all():
if pool:
pool.shutdown()
-atexit.register(_shutdown_all)
+ExitHelper().register(_shutdown_all)
class ThreadPool(object):
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/main/python/ambari_agent/main.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/main.py b/ambari-agent/src/main/python/ambari_agent/main.py
index 5972717..b8becc8 100644
--- a/ambari-agent/src/main/python/ambari_agent/main.py
+++ b/ambari-agent/src/main/python/ambari_agent/main.py
@@ -36,6 +36,7 @@ from NetUtil import NetUtil
from PingPortListener import PingPortListener
import hostname
from DataCleaner import DataCleaner
+from ExitHelper import ExitHelper
import socket
from ambari_commons import OSConst, OSCheck
from ambari_commons.shell import shellRunner
@@ -278,6 +279,7 @@ def main(heartbeat_stop_callback=None):
controller.start()
controller.join()
if not OSCheck.get_os_family() == OSConst.WINSRV_FAMILY:
+ ExitHelper.execute_cleanup()
stop_agent()
logger.info("finished")
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/test/python/ambari_agent/TestController.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestController.py b/ambari-agent/src/test/python/ambari_agent/TestController.py
index a202ba4..4559331 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestController.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestController.py
@@ -35,6 +35,7 @@ from ambari_agent import hostname
from ambari_agent.Controller import AGENT_AUTO_RESTART_EXIT_CODE
from ambari_commons import OSCheck
from ambari_agent.Hardware import Hardware
+from ambari_agent.ExitHelper import ExitHelper
import ambari_commons
OPERATING_SYSTEM_DISTRO = ('Suse','11','Final')
@@ -334,12 +335,12 @@ class TestController(unittest.TestCase):
self.assertTrue(sendRequestMock.call_count > 5)
- @patch("sys.exit")
- def test_restartAgent(self, sys_exit_mock):
+ @patch.object(ExitHelper, "exit")
+ def test_restartAgent(self, exit_mock):
self.controller.restartAgent()
- self.assertTrue(sys_exit_mock.called)
- self.assertTrue(sys_exit_mock.call_args[0][0] == AGENT_AUTO_RESTART_EXIT_CODE)
+ self.assertTrue(exit_mock.called)
+ self.assertTrue(exit_mock.call_args[0][0] == AGENT_AUTO_RESTART_EXIT_CODE)
@patch("urllib2.Request")
http://git-wip-us.apache.org/repos/asf/ambari/blob/62c8b703/ambari-agent/src/test/python/ambari_agent/TestMain.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestMain.py b/ambari-agent/src/test/python/ambari_agent/TestMain.py
index 3c20997..8c8d347 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestMain.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestMain.py
@@ -45,7 +45,7 @@ with patch.object(OSCheck, "os_distribution", new = MagicMock(return_value = os_
from ambari_agent.DataCleaner import DataCleaner
import ambari_agent.HeartbeatHandlers as HeartbeatHandlers
from ambari_commons.os_check import OSConst, OSCheck
-
+ from ambari_agent.ExitHelper import ExitHelper
if get_platform() != PLATFORM_WINDOWS:
from ambari_commons.shell import shellRunnerLinux
@@ -306,7 +306,8 @@ class TestMain(unittest.TestCase):
@patch.object(DataCleaner,"__init__")
@patch.object(PingPortListener,"start")
@patch.object(PingPortListener,"__init__")
- def test_main(self, ping_port_init_mock, ping_port_start_mock, data_clean_init_mock,data_clean_start_mock,
+ @patch.object(ExitHelper,"execute_cleanup")
+ def test_main(self, cleanup_mock, ping_port_init_mock, ping_port_start_mock, data_clean_init_mock,data_clean_start_mock,
parse_args_mock, join_mock, start_mock, Controller_init_mock, try_to_connect_mock,
update_log_level_mock, daemonize_mock, perform_prestart_checks_mock,
ambari_config_mock,
@@ -339,7 +340,7 @@ class TestMain(unittest.TestCase):
self.assertTrue(data_clean_start_mock.called)
self.assertTrue(ping_port_init_mock.called)
self.assertTrue(ping_port_start_mock.called)
-
+ self.assertTrue(cleanup_mock.called)
perform_prestart_checks_mock.reset_mock()
# Testing call with --expected-hostname parameter