Skip to content

Commit

Permalink
feat: add progress status for docker env (#215)
Browse files Browse the repository at this point in the history
* add progress status for docker env
  • Loading branch information
XianBW authored Aug 19, 2024
1 parent 975c327 commit 538d4ef
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions rdagent/utils/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
# TODO: move the scenario specific docker env into other folders.

import json
import os
import subprocess
import sys
Expand All @@ -19,6 +20,7 @@
import docker.models.containers
from pydantic import BaseModel
from pydantic_settings import BaseSettings
from rich.progress import Progress, TextColumn

from rdagent.log import rdagent_logger as logger

Expand Down Expand Up @@ -189,14 +191,55 @@ def prepare(self):
client = docker.from_env()
if self.conf.build_from_dockerfile and self.conf.dockerfile_folder_path.exists():
logger.info(f"Building the image from dockerfile: {self.conf.dockerfile_folder_path}")
image, logs = client.images.build(
resp_stream = client.api.build(
path=str(self.conf.dockerfile_folder_path), tag=self.conf.image, network_mode=self.conf.network
)
if isinstance(resp_stream, str):
logger.info(resp_stream)
with Progress(TextColumn("{task.description}")) as p:
task = p.add_task("[cyan]Building image...")
for part in resp_stream:
status_dict = json.loads(part)
if "error" in status_dict:
p.update(task, description=f"[red]error: {status_dict['error']}")
raise docker.errors.BuildError(status_dict["error"])
if "stream" in status_dict:
p.update(task, description=status_dict["stream"])
logger.info(f"Finished building the image from dockerfile: {self.conf.dockerfile_folder_path}")
try:
client.images.get(self.conf.image)
except docker.errors.ImageNotFound:
client.images.pull(self.conf.image)
image_pull = client.api.pull(self.conf.image, stream=True, decode=True)
current_status = ""
layer_set = set()
completed_layers = 0
with Progress(TextColumn("{task.description}"), TextColumn("{task.fields[progress]}")) as sp:
main_task = sp.add_task("[cyan]Pulling image...", progress="")
status_task = sp.add_task("[bright_magenta]layer status", progress="")
for line in image_pull:
if "error" in line:
sp.update(status_task, description=f"[red]error", progress=line["error"])
raise docker.errors.APIError(line["error"])

layer_id = line["id"]
status = line["status"]
p_text = line.get("progress", None)

if layer_id not in layer_set:
layer_set.add(layer_id)

if p_text:
current_status = p_text

if status == "Pull complete" or status == "Already exists":
completed_layers += 1

sp.update(main_task, progress=f"[green]{completed_layers}[white]/{len(layer_set)} layers completed")
sp.update(
status_task,
description=f"[bright_magenta]layer {layer_id} [yellow]{status}",
progress=current_status,
)
except docker.errors.APIError as e:
raise RuntimeError(f"Error while pulling the image: {e}")

Expand Down

0 comments on commit 538d4ef

Please sign in to comment.