mcp-agent mode for mcp-checker with web-info and REST API
New:
- agent index page serving on 0.0.0.0:8765
- REST API with modular approach to modules
- 'fio' module working via thread-safe Thread able to return
real-time info on its status
- 'fio' module scheduled run option
- ability to preserve multiple testrun results while active
- dockerfile for agent image
Fixed:
- Network report fixes to work on Kube envs
- Fixed function for running commands inside daemonset pods
Related-PROD: PROD-36669
Change-Id: I57e73001247af9187680bfc5744590eef219d93c
diff --git a/cfg_checker/nodes.py b/cfg_checker/nodes.py
index ef2219c..1dcec2a 100644
--- a/cfg_checker/nodes.py
+++ b/cfg_checker/nodes.py
@@ -509,6 +509,7 @@
# prepare needed resources
self._check_namespace()
self._scripts = self._check_config_map()
+ self.prepared_daemonsets = []
def _check_namespace(self):
# ensure namespace
@@ -984,7 +985,11 @@
# create daemonset
logger_cli.debug("... preparing daemonset")
- return self.kube.prepare_daemonset_from_yaml(self._namespace, _ds)
+ _ds = self.kube.prepare_daemonset_from_yaml(self._namespace, _ds)
+ # Save prepared daemonset
+ self.prepared_daemonsets.append(_ds)
+ # return it
+ return _ds
def wait_for_daemonset(self, ds, timeout=120):
# iteration timeout
@@ -1076,7 +1081,13 @@
)
return _result
- def execute_script_on_daemon_set(self, ds, script_filename, args=None):
+ def execute_cmd_on_daemon_set(
+ self,
+ ds,
+ cmd,
+ args=None,
+ is_script=False
+ ):
"""
Query daemonset for pods and execute script on all of them
"""
@@ -1090,6 +1101,7 @@
plist[2], # namespace
strict=True,
_request_timeout=120,
+ arguments=plist[5]
)
]
@@ -1103,16 +1115,24 @@
)
_plist = []
_arguments = args if args else ""
- _cmd = [
- "python3",
- os.path.join(
- "/",
- self.env_config.kube_scripts_folder,
- script_filename
- ),
- _arguments
- ]
- _cmd = " ".join(_cmd)
+ if is_script:
+ _cmd = [
+ "python3",
+ os.path.join(
+ "/",
+ self.env_config.kube_scripts_folder,
+ cmd
+ ),
+ _arguments
+ ]
+ _cmd = " ".join(_cmd)
+ else:
+ # decide if we are to wrap it to bash
+ if '|' in cmd:
+ _cmd = "bash -c"
+ _arguments = cmd
+ else:
+ _cmd = cmd
for item in _pods.items:
_plist.append(
[
@@ -1120,12 +1140,12 @@
item.spec.node_name,
item.metadata.namespace,
item.metadata.name,
- _cmd
+ _cmd,
+ _arguments
]
)
# map func and cmd
- logger_cli
pool = Pool(self.env_config.threads)
_results = {}
self.not_responded = []
@@ -1202,3 +1222,48 @@
# TODO: Exception handling
return _target_path
+
+ def get_cmd_for_nodes(self, cmd, target_key, target_dict=None, nodes=None):
+ """Function runs command on daemonset and parses result into place
+ or into dict structure provided
+
+ :return: no return value, data pulished internally
+ """
+ logger_cli.debug(
+ "... collecting results for '{}'".format(cmd)
+ )
+ if target_dict:
+ _nodes = target_dict
+ else:
+ _nodes = self.nodes
+ # Dirty way to get daemonset that was used in checker and not deleted
+ _ds = self.prepared_daemonsets[0]
+ _result = self.execute_cmd_on_daemon_set(_ds, cmd)
+ for node, data in _nodes.items():
+
+ if node in self.skip_list:
+ logger_cli.debug(
+ "... '{}' skipped while collecting '{}'".format(
+ node,
+ cmd
+ )
+ )
+ continue
+ # Prepare target key
+ if target_key not in data:
+ data[target_key] = None
+ # Save data
+ if data['status'] in [NODE_DOWN, NODE_SKIP]:
+ data[target_key] = None
+ elif node not in _result:
+ continue
+ elif not _result[node]:
+ logger_cli.debug(
+ "... '{}' not responded after '{}'".format(
+ node,
+ self.env_config.salt_timeout
+ )
+ )
+ data[target_key] = None
+ else:
+ data[target_key] = _result[node]