jw/pkg/lib/util.run_cmd(): Chunked read_stream()

jw-pkg distro dup got hung in a chroot environment. strace shows that
write(2) into a pipe is the hanging syscall, with the write buffer
hinting at zypper dup output.

I strongly suspect that run_cmd() tries to write stdout into the pipe
which read_stream() fails to empty. So, make read_stream() more
resilient by using read(4096) instead of readline(), which I suspect
to be prone to hang on overlong lines.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-03-04 08:45:38 +01:00 committed by janware DevOps
commit ae902250bd

View file

@ -172,13 +172,20 @@ async def run_cmd(
stderr_log_enc = output_encoding stderr_log_enc = output_encoding
async def read_stream(stream, prio, collector: list[bytes], log_enc: str): async def read_stream(stream, prio, collector: list[bytes], log_enc: str):
buf = b""
while True: while True:
line = await stream.readline() chunk = await stream.read(4096)
if not line: if not chunk:
break break
collector.append(line) collector.append(chunk)
if verbose: if verbose:
__log(prio, line.decode(log_enc, errors="replace").rstrip("\n")) buf += chunk
while b"\n" in buf:
line, buf = buf.split(b"\n", 1)
__log(prio, line.decode(log_enc, errors="replace"))
if verbose and buf:
# flush trailing partial line (no newline)
__log(prio, buf.decode(log_enc, errors="replace"))
tasks = [ tasks = [
asyncio.create_task( asyncio.create_task(