Simplify deploy streaming by removing tail buffering

This commit is contained in:
kevinveenbirkenbach committed 2026-03-16 12:24:53 +01:00
1 parent 27133e3292
commit 43e623ccbd
3 files changed
+10 -41

No files matched your search

+3 -13
View File
@@ -39,7 +39,6 @@ class Compose:
check: bool = True,
capture: bool = False,
live: bool = False,
keep_lines: int = 400,
text: bool = True,
extra_env: dict[str, str] | None = None,
) -> subprocess.CompletedProcess:
@@ -49,9 +48,7 @@ class Compose:
env.update({k: str(v) for k, v in extra_env.items()})
if live:
r = run_streaming(
cmd, cwd=self.repo_root, env=env, keep_lines=keep_lines, text=text
)
r = run_streaming(cmd, cwd=self.repo_root, env=env, text=text)
else:
r = subprocess.run(
cmd,
@@ -158,8 +155,7 @@ class Compose:
["sh", "-lc", "/opt/src/infinito/scripts/docker/entry.sh true"],
workdir="/opt/src/infinito",
check=False,
live=True, # <--- live output
keep_lines=400, # <--- tail for failure printing
live=True,
extra_env={
"ANSIBLE_FORCE_COLOR": "1",
"PY_COLORS": "1",
@@ -168,10 +164,6 @@ class Compose:
)
if r.returncode != 0:
print("===== entry.sh stdout (tail) =====")
print((r.stdout or "").rstrip() or "<empty>")
print("===== entry.sh stderr (tail) =====")
print((r.stderr or "").rstrip() or "<empty>")
raise RuntimeError(f"entry.sh init failed (rc={r.returncode})")
def down(self) -> None:
@@ -193,7 +185,6 @@ class Compose:
workdir: str | None = None,
capture: bool = False,
live: bool = False,
keep_lines: int = 400,
tty: bool | None = None,
extra_env: dict[str, str] | None = None,
) -> subprocess.CompletedProcess:
@@ -206,7 +197,7 @@ class Compose:
- tty=False -> -T (CI safe)
Streaming:
- live=True streams stdout/stderr to terminal while keeping a tail buffer.
- live=True streams stdout/stderr to terminal.
"""
if tty is None:
tty = not self._is_ci()
@@ -229,7 +220,6 @@ class Compose:
check=check,
capture=capture,
live=live,
keep_lines=keep_lines,
)
def _get_infinito_container_id(self) -> str:
+1 -10
View File
@@ -38,13 +38,11 @@ def _run_deploy(
if passthrough:
cmd.extend(passthrough)
# Live stream output for immediate visibility,
# while keeping a tail buffer for post-failure printing.
# Live stream output for immediate visibility.
r = compose.exec(
cmd,
check=False,
live=True,
keep_lines=400,
extra_env={
# Force ANSI colors even when no TTY is allocated (CI default).
"ANSIBLE_FORCE_COLOR": "1",
@@ -53,13 +51,6 @@ def _run_deploy(
},
)
if r.returncode != 0:
print("===== deploy stdout (tail) =====")
print((r.stdout or "").rstrip() or "<empty>")
print("===== deploy stderr (tail) =====")
print((r.stderr or "").rstrip() or "<empty>")
print("===============================")
return int(r.returncode)
+6 -18
View File
@@ -3,24 +3,21 @@ from __future__ import annotations
import sys
import subprocess
import threading
from collections import deque
from typing import Deque, TextIO
from typing import TextIO
def _drain_stream(
stream: TextIO,
*,
sink: TextIO,
buf: Deque[str],
) -> None:
"""
Read a text stream line-by-line, write to sink, and keep a tail buffer.
Read a text stream line-by-line and write to sink.
"""
try:
for line in iter(stream.readline, ""):
sink.write(line)
sink.flush()
buf.append(line.rstrip("\n"))
finally:
try:
stream.close()
@@ -34,13 +31,10 @@ def run_streaming(
*,
cwd,
env: dict[str, str],
keep_lines: int = 400,
text: bool = True,
) -> subprocess.CompletedProcess:
"""
Run a subprocess, stream stdout/stderr live to the terminal, and return
a CompletedProcess whose stdout/stderr contain only the last `keep_lines`
lines (tail buffers).
Run a subprocess and stream stdout/stderr live to the terminal.
"""
p = subprocess.Popen(
cmd,
@@ -52,19 +46,16 @@ def run_streaming(
bufsize=1, # line buffered (best effort)
)
out_buf: Deque[str] = deque(maxlen=int(keep_lines))
err_buf: Deque[str] = deque(maxlen=int(keep_lines))
assert p.stdout is not None
assert p.stderr is not None
t_out = threading.Thread(
target=_drain_stream,
kwargs={"stream": p.stdout, "sink": sys.stdout, "buf": out_buf},
kwargs={"stream": p.stdout, "sink": sys.stdout},
)
t_err = threading.Thread(
target=_drain_stream,
kwargs={"stream": p.stderr, "sink": sys.stderr, "buf": err_buf},
kwargs={"stream": p.stderr, "sink": sys.stderr},
)
t_out.daemon = True
@@ -78,7 +69,4 @@ def run_streaming(
t_out.join()
t_err.join()
stdout_tail = ("\n".join(out_buf) + ("\n" if out_buf else "")).rstrip("\n")
stderr_tail = ("\n".join(err_buf) + ("\n" if err_buf else "")).rstrip("\n")
return subprocess.CompletedProcess(cmd, rc, stdout=stdout_tail, stderr=stderr_tail)
return subprocess.CompletedProcess(cmd, rc)