Skip to content

Mcp get log job fallback - #314

Open
bhcopeland wants to merge 1 commit into
kernelci:mainfrom
bhcopeland:mcp-get-log-job-fallback
Open

Mcp get log job fallback#314
bhcopeland wants to merge 1 commit into
kernelci:mainfrom
bhcopeland:mcp-get-log-job-fallback

Conversation

@bhcopeland

Copy link
Copy Markdown
Member

A job that fails before producing results never reaches the dashboard, so get_log could not fetch its log at all. Reported by @yogeshlal while testing #306 against a triage agent: a node whose device failed to flash returns "not found" from both get_log and get_build, while Maestro holds it as an incomplete job with the LAVA callback attached.

get_log now falls back to that callback when the dashboard has no test for the id, and accepts the id in either form since Maestro takes the bare hex and the dashboard takes it origin-prefixed. The callback is JSON rather than a log file, so it cannot be streamed into a bounded buffer; it is capped on both the download and the decompressed size, with the same deadline as the dashboard path. The response reports which source was used.

get_node already returns the infra diagnosis for these nodes and is usually the better answer; this is for when the raw log is wanted.

Based on #306, which needs to merge first.

@aliceinwire

Copy link
Copy Markdown
Member

please rebase

@bhcopeland
bhcopeland force-pushed the mcp-get-log-job-fallback branch 2 times, most recently from 12a0c90 to f2ba72c Compare September 3, 2026 07:30
A job that fails before producing results never reaches the dashboard,
so get_log could not fetch its log at all: get_log and get_build both
return "not found", while Maestro holds it as an incomplete job with the
LAVA callback attached.

Fall back to that callback when the dashboard has no test for the id.
The id is accepted in either form, since Maestro takes the bare hex and
the dashboard takes it origin-prefixed.

The callback is a JSON document rather than a log file, so it cannot be
streamed into a bounded buffer. It is capped at MAX_CALLBACK_BYTES on
both the download and the decompressed size, and the extracted log is
then bounded as before. The response reports which source was used.

Reported-by: Yogesh Lal <yogesh.lal@oss.qualcomm.com>
Signed-off-by: Ben Copeland <ben.copeland@linaro.org>
@bhcopeland
bhcopeland force-pushed the mcp-get-log-job-fallback branch from f2ba72c to 2b8625d Compare September 3, 2026 10:35
Comment thread kcidev/api.py
raise KciDevError("Log gzip stream is incomplete or malformed")


def _bare_node_id(node_id):

@aliceinwire aliceinwire Sep 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback can return a Maestro log for a non-Maestro ID as any Dashboard "not found" result triggers _job_callback_log()
If the Dashboard does not contain other-origin:abcdef, but Maestro happens to contain node abcdef, get_log() could return an unrelated Maestro job's log instead of reporting that the original test was not found.

Comment thread kcidev/api.py
raw = bytes(body)
if raw[:2] == b"\x1f\x8b":
expanded = bytearray()
for piece in _gunzip_iter(iter([raw])):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

malformed gzip can leak zlib.error

Comment thread tests/test_api.py
"kind": "job",
"result": "incomplete",
"data": {"error_code": "Infrastructure", "error_msg": "Unable to flash"},
"artifacts": {"callback_data": callback_url} if callback_url else {},

@aliceinwire aliceinwire Sep 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current KernelCI pipeline says

# Temporarily we dont remove log field
# data.pop('log', None)

Maybe consider lava_log -> lava_logs -> callback_data["log"] or otherwise explain/document why depending on the temporary callback log field is intentional.

@aliceinwire

Copy link
Copy Markdown
Member

kcidev/api.py now imports gzip, but the production implementation does not use it. The tests import gzip locally instead.

@aliceinwire

Copy link
Copy Markdown
Member

Please restrict the Maestro fallback to bare IDs or IDs explicitly prefixed with maestro:. Currently _bare_node_id() strips any origin prefix, so a missing other-origin: Dashboard test could accidentally resolve and return an unrelated Maestro log. Please preserve the Dashboard error for non-Maestro origins and add a regression test for this case.

@aliceinwire

Copy link
Copy Markdown
Member

_job_callback_log() can call _gunzip_iter(), but unlike the normal Dashboard log path it does not catch zlib.error. A malformed gzip callback can therefore leak a raw exception from KernelCIClient.get_log() instead of KciDevError. Please catch zlib.error here and add a malformed-gzip regression test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants