Pull progress: split the stream on CR too
docker refreshes Downloading lines with \r, not \n -- readline()
parked them in the buffer, so the byte snapshots never surfaced and
the overall-progress dict stayed empty (the ⏳ summary never printed).
Chunked reads now split on both terminators; verified with a synthetic
\r-stream that the parser yields the refresh lines and computes the
52.2/65.1MB-style summary.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e41cd48272
commit
3ae1578325
@ -114,7 +114,7 @@ def _pull_one(image: str, verbose: bool = True) -> None:
|
||||
# per-layer lines; forward the informative ones (throttled).
|
||||
proc = subprocess.Popen(['docker', 'pull', ref],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
text=True, bufsize=1)
|
||||
bufsize=0)
|
||||
last_line = ''
|
||||
last_show = 0.0
|
||||
layer_prog = {} # layer id -> (done_bytes, total_bytes): the raw
|
||||
@ -130,8 +130,33 @@ def _pull_one(image: str, verbose: bool = True) -> None:
|
||||
return int(float(s[:-len(suf)]) * m)
|
||||
return int(float(s or 0))
|
||||
|
||||
for line in proc.stdout:
|
||||
last_line = line.strip()
|
||||
# docker progress lines end with \r (carriage-return refresh), not
|
||||
# \n -- readline() buffered them until a rare \n arrived, so the
|
||||
# Downloading snapshots (and the ⏳ summary fed by them) never
|
||||
# surfaced. Split on BOTH terminators, chunked reads.
|
||||
import io as _io
|
||||
stream = _io.TextIOWrapper(proc.stdout, errors='replace')
|
||||
buf = ''
|
||||
_lines_iter = iter(lambda: None, 1) # placeholder, replaced below
|
||||
|
||||
def _iter_lines():
|
||||
nonlocal buf
|
||||
while True:
|
||||
chunk = stream.read(512)
|
||||
if not chunk:
|
||||
if buf:
|
||||
yield buf
|
||||
return
|
||||
buf += chunk
|
||||
parts = buf.split('\r') if '\r' in buf else buf.split('\n')
|
||||
if len(parts) > 1:
|
||||
for p in parts[:-1]:
|
||||
yield p
|
||||
buf = parts[-1]
|
||||
|
||||
for line in _iter_lines():
|
||||
line = line.strip('\n ')
|
||||
last_line = line
|
||||
m = _re.match(r'^([0-9a-f]{12}): Downloading.*?([\d.]+[kKMG]?B)/([\d.]+[kKMG]?B)', line)
|
||||
if m:
|
||||
layer_prog[m.group(1)] = (_bytes(m.group(2)), _bytes(m.group(3)))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user