Skip to content

Commit

Permalink
osbuild: add result error reporting for sources
Browse files Browse the repository at this point in the history
This commit adds error reporting from source download errors
to the monitor. It reuses the `BuildResult` for symmetry but
we probably want to refactor this a bit to make source handling
a bit more similar to stages.
  • Loading branch information
mvo5 committed Nov 14, 2024
1 parent 4ceac0c commit d995ce2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
12 changes: 6 additions & 6 deletions osbuild/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def log_entry(
message: Optional[str] = None,
context: Optional[Context] = None,
progress: Optional[Progress] = None,
build_result: Optional[osbuild.pipeline.BuildResult] = None,
result: Optional[osbuild.pipeline.BuildResult | osbuild.pipeline.DownloadResult] = None,
) -> dict:
"""
Create a single log entry dict with a given message, context, and progress objects.
Expand All @@ -177,7 +177,7 @@ def log_entry(
# monitors support that
return omitempty({
"message": message,
"build_result": build_result.as_dict() if build_result else None,
"result": result.as_dict() if result else None,
"context": context.as_dict() if context else None,
"progress": progress.as_dict() if progress else None,
"timestamp": time.time(),
Expand Down Expand Up @@ -231,7 +231,7 @@ def stage(self, stage: osbuild.Stage):
def assembler(self, assembler: osbuild.Stage):
"""Called when an assembler is being built"""

def result(self, result: osbuild.pipeline.BuildResult):
def result(self, result: osbuild.pipeline.BuildResult | osbuild.pipeline.DownloadResult) -> None:
"""Called when a module (stage/assembler) is done with its result"""

def log(self, message: str, origin: Optional[str] = None):
Expand All @@ -258,7 +258,7 @@ def __init__(self, fd: int, total_steps: int = 0):
super().__init__(fd, total_steps)
self.timer_start = 0

def result(self, result: osbuild.pipeline.BuildResult):
def result(self, result: osbuild.pipeline.BuildResult | osbuild.pipeline.DownloadResult) -> None:
duration = int(time.time() - self.timer_start)
self.out.write(f"\n⏱ Duration: {duration}s\n")

Expand Down Expand Up @@ -339,7 +339,7 @@ def _module(self, module: osbuild.Stage):
self.log(f"Starting module {module.name}", origin="osbuild.monitor")

# result is for modules
def result(self, result: osbuild.pipeline.BuildResult):
def result(self, result: osbuild.pipeline.BuildResult | osbuild.pipeline.DownloadResult) -> None:
# we may need to check pipeline ids here in the future
if self._progress.sub_progress:
self._progress.sub_progress.incr()
Expand All @@ -351,7 +351,7 @@ def result(self, result: osbuild.pipeline.BuildResult):
# We should probably remove the "output" key from the result
# as it is redundant, each output already generates a "log()"
# message that is streamed to the client.
build_result=result,
result=result,
))

def log(self, message, origin: Optional[str] = None):
Expand Down
24 changes: 23 additions & 1 deletion osbuild/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ def as_dict(self) -> Dict[str, Any]:
return vars(self)


class DownloadResult:
def __init__(self, name: str, source_id: str, success: bool) -> None:
self.name = name
self.id = source_id
self.success = success
self.output = ""

def as_dict(self) -> Dict[str, Any]:
return vars(self)


class Stage:
def __init__(self, info, source_options, build, base, options, source_epoch):
self.info = info
Expand Down Expand Up @@ -418,8 +429,19 @@ def download(self, store, monitor):
for source in self.sources:
# Workaround for lack of progress from sources, this
# will need to be reworked later.
dr = DownloadResult(source.name, source.id, success=True)
monitor.begin(source)
source.download(mgr, store)
try:
source.download(mgr, store)
except host.RemoteError as e:
dr.success = False
dr.output = str(e)
monitor.result(dr)
raise e
monitor.result(dr)
# ideally we would make the whole of download more symmetric
# to "build_stages" and return a "results" here in "finish"
# as well
monitor.finish({"name": source.info.name})

def depsolve(self, store: ObjectStore, targets: Iterable[str]) -> List[str]:
Expand Down

0 comments on commit d995ce2

Please sign in to comment.