diff options
author | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-05-08 17:13:23 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2025-05-09 10:27:51 +0200 |
commit | 3ddde7ba476d8dab4a8f18bf9fe00bc40f5b99ac (patch) | |
tree | 06ca0ee46eb1f3673d8cceb45e4a9e6a4e3050af /doc/invocations-http-server | |
parent | dd6be011609937477516344d217a24aadf92fcd2 (diff) | |
download | justbuild-3ddde7ba476d8dab4a8f18bf9fe00bc40f5b99ac.tar.gz |
Invocation server: support filtering by remote-execution property
When looking at an invocation, it can be helpful to quickly get
all other invocation that coincide with a specific remote-execution
property (like the build image). Support this use case by adding
appropriate filtering and links.
Diffstat (limited to 'doc/invocations-http-server')
-rwxr-xr-x | doc/invocations-http-server/server.py | 46 | ||||
-rw-r--r-- | doc/invocations-http-server/templates/invocation.html | 18 | ||||
-rw-r--r-- | doc/invocations-http-server/templates/invocations.html | 4 |
3 files changed, 61 insertions, 7 deletions
diff --git a/doc/invocations-http-server/server.py b/doc/invocations-http-server/server.py index 0cd3c20d..0bcdca1a 100755 --- a/doc/invocations-http-server/server.py +++ b/doc/invocations-http-server/server.py @@ -30,6 +30,9 @@ def core_config(conf): new_conf[k] = v return new_conf +class HexIdentifierConverter(werkzeug.routing.BaseConverter): + regex = '[a-zA-Z0-9]{2,300}' + class HashIdentifierConverter(werkzeug.routing.BaseConverter): regex = '[a-zA-Z0-9]{40,51}' @@ -61,6 +64,8 @@ class InvocationServer: rule = werkzeug.routing.Rule self.routingmap = werkzeug.routing.Map([ rule("/", methods=("GET",), endpoint="list_invocations"), + rule("/filterinvocations/remote/prop/<hexidentifier:key>/<hexidentifier:value>", + endpoint="filter_remote_prop"), rule("/blob/<hashidentifier:blob>", methods=("GET",), endpoint="get_blob"), @@ -76,6 +81,7 @@ class InvocationServer: ], converters=dict( invocationidentifier=InvocationIdentifierConverter, hashidentifier=HashIdentifierConverter, + hexidentifier=HexIdentifierConverter, fileidentifier=FileIdentifierConverter, )) @@ -95,7 +101,9 @@ class InvocationServer: response.data = template.render(params).encode("utf8") return response - def do_list_invocations(self): + def do_list_invocations(self, *, + filter_info="", + profile_filter = lambda p : True): invocations = [] count = 0 entries = sorted(os.listdir(self.logsdir), reverse=True) @@ -111,6 +119,8 @@ class InvocationServer: profile_data = json.load(f) except: profile_data = {} + if not profile_filter(profile_data): + continue count += 1 target = profile_data.get("target") config = profile_data.get("configuration", {}) @@ -128,7 +138,28 @@ class InvocationServer: if count >= 50: break return self.render("invocations.html", - {"invocations": invocations}) + {"invocations": invocations, + "filter_info": filter_info}) + + def do_filter_remote_prop(self, key, value): + filter_info = "remote-execution property" + try: + key_string = bytes.fromhex(key).decode('utf-8') + value_string = bytes.fromhex(value).decode('utf-8') + filter_info += " " + json.dumps({key_string: value_string}) + except: + pass + + def check_prop(p): + for k, v in p.get('remote', {}).get('properties', {}).items(): + if (k.encode().hex() == key) and (v.encode().hex() == value): + return True + return False + + return self.do_list_invocations( + filter_info = filter_info, + profile_filter = check_prop, + ) def process_failure(self, cmd, procobj, *, failure_kind=None): params = {"stdout": None, "stderr": None, "failure_kind": failure_kind} @@ -230,8 +261,15 @@ class InvocationServer: params["exit_code"] = profile.get('exit code') params["analysis_errors"] = profile.get('analysis errors', []) params["remote_address"] = profile.get('remote', {}).get('address') - params["remote_props"] = json.dumps( - profile.get('remote', {}).get('properties', {})) + remote_props = [] + for k, v in profile.get('remote', {}).get('properties', {}).items(): + remote_props.append({ + "key": k, + "key_hex": k.encode().hex(), + "value": v, + "value_hex": v.encode().hex(), + }) + params["remote_props"] = remote_props params["remote_dispatch"] = json.dumps( profile.get('remote', {}).get('dispatch', [])) # For complex conditional data fill with None as default diff --git a/doc/invocations-http-server/templates/invocation.html b/doc/invocations-http-server/templates/invocation.html index 62d98813..816f5344 100644 --- a/doc/invocations-http-server/templates/invocation.html +++ b/doc/invocations-http-server/templates/invocation.html @@ -96,9 +96,21 @@ Inocations {{invocation | e}} {% if remote_address %} <li> remote <ul> - <li> address: <tt>{{ remote_address | e }}</tt> - <li> properties: <tt>{{ remote_props | e}}</tt> - <li> dispatch: <tt>{{ remote_dispatch | e }}</tt> + <li> address: <tt>{{ remote_address | e }}</tt></li> + {% if remote_props %} + <li> properties: + <ul> + {% for prop in remote_props %} + <li> <tt>{{ prop["key"] | e }}</tt> : + <a href="/filterinvocations/remote/prop/{{ prop["key_hex"] | e }}/{{ prop["value_hex"] }}"><tt>{{ prop["value"] | e }}</tt></a> + </li> + {% endfor %} + </ul> + </li> + {% else %} + <li> properties: <i>(none)</i> + {% endif %} + <li> dispatch: <tt>{{ remote_dispatch | e }}</tt></li> </ul> </li> {% endif %} diff --git a/doc/invocations-http-server/templates/invocations.html b/doc/invocations-http-server/templates/invocations.html index f2212af0..c12b19cf 100644 --- a/doc/invocations-http-server/templates/invocations.html +++ b/doc/invocations-http-server/templates/invocations.html @@ -4,7 +4,11 @@ Recent Invocations {% endblock %} {% block content %} +{% if filter_info %} +<h1>Invocations filtered by {{ filter_info | e }}</h1> +{% else %} <h1>Recent Invocations</h1> +{% endif %} {% if invocations %} <ul> {% for invocation in invocations %} |