-
Notifications
You must be signed in to change notification settings - Fork 107
Proper Tool Metadata Abstraction #1787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b8120c0
537ade5
4211f5d
483e912
de68fa5
0f2b857
41bc4e7
be289b2
ab8c978
950b25d
a8a92d8
90bdcd8
619e0c6
9d692af
05279e1
03bd176
cc96795
065c838
cb421c2
8ff01e9
7ef2b32
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| { | ||
| "transient":{ | ||
| "blktrace": null, | ||
| "bpftrace": null, | ||
| "cpuacct": null, | ||
| "disk": null, | ||
| "dm-cache": null, | ||
| "docker": null, | ||
| "docker-info": null, | ||
| "external-data-source": null, | ||
| "haproxy-ocp": null, | ||
| "iostat": null, | ||
| "jmap": null, | ||
| "jstack": null, | ||
| "kvm-spinlock": null, | ||
| "kvmstat": null, | ||
| "kvmtrace": null, | ||
| "lockstat": null, | ||
| "mpstat": null, | ||
| "numastat": null, | ||
| "oc": null, | ||
| "openvswitch": null, | ||
| "pcp": null, | ||
| "perf": null, | ||
| "pidstat": null, | ||
| "pprof": null, | ||
| "proc-interrupts": null, | ||
| "proc-sched_debug": null, | ||
| "proc-vmstat": null, | ||
| "prometheus-metrics": null, | ||
| "qemu-migrate": null, | ||
| "rabbit": null, | ||
| "sar": null, | ||
| "strace": null, | ||
| "sysfs": null, | ||
| "systemtap": null, | ||
| "tcpdump": null, | ||
| "turbostat": null, | ||
| "user-tool": null, | ||
| "virsh-migrate": null, | ||
| "vmstat": null | ||
| }, | ||
|
|
||
| "persistent":{ | ||
| "node-exporter": {"collector": "prometheus", "port": "9100"}, | ||
| "dcgm": {"collector": "prometheus", "port": "8000"} | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,6 @@ Available tools: | |
| blktrace | ||
| bpftrace | ||
| cpuacct | ||
| dcgm | ||
|
||
| disk | ||
| dm-cache | ||
| docker | ||
|
|
@@ -34,7 +33,6 @@ Available tools: | |
| kvmtrace | ||
| lockstat | ||
| mpstat | ||
| node-exporter | ||
| numastat | ||
| oc | ||
| openvswitch | ||
|
|
@@ -57,6 +55,8 @@ Available tools: | |
| user-tool | ||
| virsh-migrate | ||
| vmstat | ||
| node-exporter | ||
| dcgm | ||
|
|
||
| For a list of tool specific options, run: | ||
| /var/tmp/pbench-test-utils/opt/pbench-agent/tool-scripts/<tool-name> --help | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| from pathlib import Path | ||
| import json | ||
| import os | ||
|
|
||
|
|
||
| class ToolMetadataExc(Exception): | ||
| pass | ||
|
|
||
|
|
||
| class ToolMetadata: | ||
| def __init__(self, mode, context, logger): | ||
| self.logger = logger | ||
| assert mode in ( | ||
| "redis", | ||
| "json", | ||
| ), f"Logic bomb! Unexpected mode, {mode}, encountered constructing tool meta data" | ||
| assert ( | ||
| context | ||
| ), "Logic bomb! No context given on ToolMetadata object construction" | ||
| self.mode = mode | ||
| if mode == "redis": | ||
| self.redis_server = context | ||
| self.json_file = None | ||
| else: | ||
| self.redis_server = None | ||
| json_path = Path(context, "tool-scripts", "meta.json") | ||
| try: | ||
| self.json = json_path.resolve(strict=True) | ||
| except FileNotFoundError: | ||
| raise ToolMetadataExc(f"missing {json_path}") | ||
| except Exception: | ||
| raise | ||
| self.data = self.__getInitialData() | ||
|
|
||
| def __getInitialData(self): | ||
| if self.mode == "json": | ||
| if not os.path.isfile(self.json): | ||
| self.logger.error( | ||
| "There is no tool-scripts/meta.json in given install dir" | ||
| ) | ||
| return None | ||
| with self.json.open("r") as json_file: | ||
| metadata = json.load(json_file) | ||
| elif self.mode == "redis": | ||
| try: | ||
| meta_raw = self.redis_server.get("tool-metadata") | ||
| except Exception: | ||
| self.logger.exception( | ||
| "Failure to fetch tool metadata from the Redis server" | ||
| ) | ||
| raise | ||
| else: | ||
| if meta_raw is None: | ||
| self.logger.error("Metadata has not been loaded into redis yet") | ||
| return None | ||
| try: | ||
| metadata = json.loads(meta_raw.decode("utf-8")) | ||
| except Exception as exc: | ||
| self.logger.error( | ||
| "Bad metadata loaded into Redis server, '%s', json=%r", | ||
| exc, | ||
| meta_raw, | ||
| ) | ||
| return None | ||
| return metadata | ||
|
|
||
| def __dataCheck(self): | ||
| if not self.data: | ||
| self.data == self.__getInitialData() | ||
| if not self.data: | ||
| self.logger.error(f"Unable to access data through {self.mode}") | ||
| return 0 | ||
| return 1 | ||
|
|
||
| def getFullData(self): | ||
| if self.__dataCheck(): | ||
| return self.data | ||
| return None | ||
|
|
||
| def getPersistentTools(self): | ||
| if self.__dataCheck(): | ||
| return list(self.data["persistent"].keys()) | ||
| return None | ||
|
|
||
| def getTransientTools(self): | ||
| if self.__dataCheck(): | ||
| return list(self.data["transient"].keys()) | ||
| return None | ||
|
|
||
| def getProperties(self, tool): | ||
| if tool in self.data["persistent"].keys(): | ||
| return self.data["persistent"][tool] | ||
| elif tool in self.data["transient"].keys(): | ||
| return self.data["transient"][tool] | ||
|
|
||
| def loadIntoRedis(self, info): | ||
| if self.mode == "redis": | ||
| try: | ||
| self.json = Path(info).resolve(strict=True) | ||
| except FileNotFoundError: | ||
| raise ToolMetadataExc(f"missing {info}") | ||
| except Exception: | ||
| raise | ||
| elif self.mode == "json": | ||
| self.redis_server = info | ||
|
|
||
| try: | ||
| with self.json.open("r") as json_file: | ||
| metadata = json.load(json_file) | ||
| self.redis_server.set("tool-metadata", json.dumps(metadata)) | ||
| except Exception: | ||
| self.logger.error("Failed to load the data into redis") | ||
| raise | ||
| return None |
Uh oh!
There was an error while loading. Please reload this page.