cfg-checker benchmark module part 2

 - fixes for fio-runner error handling
 - fixes for web-server error handling
 - proper handling of 'scheduled_to' option
 - cleanup procedure
 - kube can wait for specific phases of svc, pod, pvc, pv

Change-Id: I9b241597e6314fed1dbc3aba5e8dee1637eea1c7
diff --git a/cfg_checker/agent/webserver.py b/cfg_checker/agent/webserver.py
index 67a4567..eacce8f 100644
--- a/cfg_checker/agent/webserver.py
+++ b/cfg_checker/agent/webserver.py
@@ -8,7 +8,9 @@
 from copy import deepcopy # noqa E402
 from platform import system, release, node # noqa E402
 
+from cfg_checker.common.log import logger # noqa E402
 from cfg_checker.common.settings import pkg_dir  # noqa E402
+from cfg_checker.common.exception import CheckerException  # noqa E402
 from cfg_checker.helpers.falcon_jinja2 import FalconTemplate  # noqa E402
 from .fio_runner import FioProcessShellRun, get_time # noqa E402
 
@@ -91,19 +93,28 @@
         resp.text = json.dumps(_status)
 
     def on_post(self, req, resp):
-        def _resp(resp, code, msg):
+        def _resp(resp, code, msg, opt={}):
             resp.status = code
             resp.content_type = "application/json"
-            resp.text = json.dumps({"error": msg})
+            resp.text = json.dumps({"error": msg, "options": opt})
         # Handle actions
-        _m = req.get_media(default_when_empty={})
+        logger.info("Getting media")
+        try:
+            _m = req.get_media(default_when_empty={})
+        except falcon.MediaMalformedError:
+            _msg = "Incorrect input data"
+            logger.error(_msg)
+            _resp(resp, falcon.HTTP_400, _msg)
+            return
         if _m:
+            logger.debug("got media object:\n{}".format(json.dumps(_m)))
             # Validate action structure
             _module = _m.get('module', "")
             _action = _m.get('action', "")
             _options = _m.get('options', {})
 
             if not _module or _module not in list(_modules.keys()):
+                logger.error("invalid module '{}'".format(_module))
                 _resp(
                     resp,
                     falcon.HTTP_400,
@@ -111,6 +122,7 @@
                 )
                 return
             elif not _action or _action not in _modules[_module]['actions']:
+                logger.error("invalid action '{}'".format(_action))
                 _resp(
                     resp,
                     falcon.HTTP_400,
@@ -120,52 +132,68 @@
             else:
                 # Handle command
                 _a = _fio.actions[_action]
-                if _action == 'get_options':
-                    resp.status = falcon.HTTP_200
-                    resp.content_type = "application/json"
-                    resp.text = json.dumps({"options": _a()})
-                elif _action == 'get_resultlist':
-                    resp.status = falcon.HTTP_200
-                    resp.content_type = "application/json"
-                    resp.text = json.dumps({"resultlist": _a()})
-                elif _action == 'get_result':
-                    if 'time' not in _options:
-                        _resp(
-                            resp,
-                            falcon.HTTP_400,
-                            "No 'time' found for '{}'".format(_action)
-                        )
-                        return
-                    _time = _options['time']
-                    resp.status = falcon.HTTP_200
-                    resp.content_type = "application/json"
-                    resp.text = json.dumps({_time: _a(_time)})
-                elif _action == 'do_singlerun':
-                    _a(_options)
-                    resp.status = falcon.HTTP_200
-                    resp.content_type = "application/json"
-                    resp.text = json.dumps({"ok": True})
-                elif _action == 'do_scheduledrun':
-                    # prepare scheduled run
+                try:
+                    if _action == 'get_options':
+                        logger.info("returning options")
+                        resp.status = falcon.HTTP_200
+                        resp.content_type = "application/json"
+                        resp.text = json.dumps({"options": _a()})
+                    elif _action == 'get_resultlist':
+                        logger.info("getting results")
+                        resp.status = falcon.HTTP_200
+                        resp.content_type = "application/json"
+                        resp.text = json.dumps({"resultlist": _a()})
+                    elif _action == 'get_result':
+                        if 'time' not in _options:
+                            _msg = "No 'time' found for '{}'".format(_action)
+                            logger.error(_msg)
+                            _resp(
+                                resp,
+                                falcon.HTTP_400,
+                                _msg
+                            )
+                            return
+                        _time = _options['time']
+                        logger.info("getting results for '{}'".format(_time))
+                        resp.status = falcon.HTTP_200
+                        resp.content_type = "application/json"
+                        resp.text = json.dumps({_time: _a(_time)})
+                    elif _action == 'do_singlerun':
+                        logger.info("executing single run")
+                        _a(_options)
+                        resp.status = falcon.HTTP_200
+                        resp.content_type = "application/json"
+                        resp.text = json.dumps({"ok": True})
+                    elif _action == 'do_scheduledrun':
+                        logger.info("executing scheduled run")
+                        # prepare scheduled run
 
-                    # Run it
-                    _a(_options)
-                    resp.status = falcon.HTTP_200
-                    resp.content_type = "application/json"
-                    resp.text = json.dumps({"ok": True})
-                else:
-                    _resp(
-                        resp,
-                        falcon.HTTP_500,
-                        "Unknown error happened for '{}/{}/{}'".format(
-                            _module,
-                            _action,
-                            _options
-                        )
-                    )
+                        # Run it
+                        _a(_options)
+                        resp.status = falcon.HTTP_200
+                        resp.content_type = "application/json"
+                        resp.text = json.dumps({"ok": True})
+                    else:
+                        _msg = "Unknown error happened for '{}/{}/{}'".format(
+                                _module,
+                                _action,
+                                _options
+                            )
+                        logger.error(_msg)
+                        _resp(resp, falcon.HTTP_500, _msg)
+                except CheckerException as e:
+                    _msg = "Error for '{}/{}':\n{}".format(
+                                _module,
+                                _action,
+                                e
+                            )
+                    logger.error(_msg)
+                    _resp(resp, falcon.HTTP_500, _msg, opt=_options)
                 return
         else:
-            _resp(resp, falcon.HTTP_400, "Empty request body")
+            _msg = "Empty request body"
+            logger.error(_msg)
+            _resp(resp, falcon.HTTP_400, _msg)
 
 
 class Index: