[oe-commits] [openembedded-core] 38/49: oeqa/utils/httpserver: Rework to avoid hangs and improve logging

git at git.openembedded.org git at git.openembedded.org
Mon Feb 25 22:28:44 UTC 2019


This is an automated email from the git hooks/post-receive script.

rpurdie pushed a commit to branch sumo
in repository openembedded-core.

commit 4eac9a5337d93b6cbd3916af97f62bb04881c9cd
Author: Richard Purdie <richard.purdie at linuxfoundation.org>
AuthorDate: Fri Nov 16 09:33:28 2018 +0000

    oeqa/utils/httpserver: Rework to avoid hangs and improve logging
    
    testimage.bbclass installs a SIGTERM handler which conflicts with the
    use of multiprocessing here. This is paritcularly problematic if the http
    service is terminated before its started and hence before its had a chance
    to reset the default signal handler (as the code was written).
    
    Instead, temporarily remove testimage's handler whilst forking the http process
    which means the correct handler is installed and won't deadlock.
    
    Also take the opportunity to add in some log messages about the server start
    and shutdown so that future debugging is easier and its clearer what the code
    is doing.
    
    (From OE-Core rev: cc0471439aa0085ca87deccf061c5b676ef12388)
    
    Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>
    Signed-off-by: Armin Kuster <akuster808 at gmail.com>
---
 meta/lib/oeqa/runtime/cases/apt.py  |  2 +-
 meta/lib/oeqa/runtime/cases/dnf.py  |  2 +-
 meta/lib/oeqa/runtime/cases/opkg.py |  2 +-
 meta/lib/oeqa/utils/httpserver.py   | 37 +++++++++++++++++++++++++++++--------
 4 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/meta/lib/oeqa/runtime/cases/apt.py b/meta/lib/oeqa/runtime/cases/apt.py
index 8d4dd35..793143f 100644
--- a/meta/lib/oeqa/runtime/cases/apt.py
+++ b/meta/lib/oeqa/runtime/cases/apt.py
@@ -18,7 +18,7 @@ class AptRepoTest(AptTest):
     @classmethod
     def setUpClass(cls):
         service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_DEB'], 'all')
-        cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip)
+        cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip, logger=cls.tc.logger)
         cls.repo_server.start()
 
     @classmethod
diff --git a/meta/lib/oeqa/runtime/cases/dnf.py b/meta/lib/oeqa/runtime/cases/dnf.py
index dd7affc..ef81a8c 100644
--- a/meta/lib/oeqa/runtime/cases/dnf.py
+++ b/meta/lib/oeqa/runtime/cases/dnf.py
@@ -55,7 +55,7 @@ class DnfRepoTest(DnfTest):
     @classmethod
     def setUpClass(cls):
         cls.repo_server = HTTPService(os.path.join(cls.tc.td['WORKDIR'], 'oe-testimage-repo'),
-                                      cls.tc.target.server_ip)
+                                      cls.tc.target.server_ip, logger=cls.tc.logger)
         cls.repo_server.start()
 
     @classmethod
diff --git a/meta/lib/oeqa/runtime/cases/opkg.py b/meta/lib/oeqa/runtime/cases/opkg.py
index 668c876..6242141 100644
--- a/meta/lib/oeqa/runtime/cases/opkg.py
+++ b/meta/lib/oeqa/runtime/cases/opkg.py
@@ -18,7 +18,7 @@ class OpkgRepoTest(OpkgTest):
     @classmethod
     def setUp(cls):
         service_repo = os.path.join(cls.tc.td['DEPLOY_DIR_IPK'], 'all')
-        cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip)
+        cls.repo_server = HTTPService(service_repo, cls.tc.target.server_ip, logger=cls.tc.logger)
         cls.repo_server.start()
 
     @classmethod
diff --git a/meta/lib/oeqa/utils/httpserver.py b/meta/lib/oeqa/utils/httpserver.py
index 7d12331..a48d499 100644
--- a/meta/lib/oeqa/utils/httpserver.py
+++ b/meta/lib/oeqa/utils/httpserver.py
@@ -1,13 +1,13 @@
 import http.server
 import multiprocessing
 import os
+import traceback
+import signal
 from socketserver import ThreadingMixIn
 
 class HTTPServer(ThreadingMixIn, http.server.HTTPServer):
 
-    def server_start(self, root_dir):
-        import signal
-        signal.signal(signal.SIGTERM, signal.SIG_DFL)
+    def server_start(self, root_dir, logger):
         os.chdir(root_dir)
         self.serve_forever()
 
@@ -18,19 +18,40 @@ class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
 
 class HTTPService(object):
 
-    def __init__(self, root_dir, host=''):
+    def __init__(self, root_dir, host='', logger=None):
         self.root_dir = root_dir
         self.host = host
         self.port = 0
+        self.logger = logger
 
     def start(self):
+        if not os.path.exists(self.root_dir):
+            self.logger.info("Not starting HTTPService for directory %s which doesn't exist" % (self.root_dir))
+            return
+
         self.server = HTTPServer((self.host, self.port), HTTPRequestHandler)
         if self.port == 0:
             self.port = self.server.server_port
-        self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir])
+        self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger])
+
+        # The signal handler from testimage.bbclass can cause deadlocks here
+        # if the HTTPServer is terminated before it can restore the standard 
+        #signal behaviour
+        orig = signal.getsignal(signal.SIGTERM)
+        signal.signal(signal.SIGTERM, signal.SIG_DFL)
         self.process.start()
+        signal.signal(signal.SIGTERM, orig)
+
+        if self.logger:
+            self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port))
+
 
     def stop(self):
-        self.server.server_close()
-        self.process.terminate()
-        self.process.join()
+        if hasattr(self, "server"):
+            self.server.server_close()
+        if hasattr(self, "process"):
+            self.process.terminate()
+            self.process.join()
+        if self.logger:
+            self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port))
+

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Openembedded-commits mailing list