Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 11, 2025

Proposed change

Containerd snapshotter reports extraction progress in elapsed seconds rather than bytes, with total: null. This causes TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType' when computing aggregate progress.

Store layer size from download phase and reuse during extraction when total is unavailable:

  • Download phase: Persist download_total in job extra data
  • Extraction phase: Fall back to download_total when total is None
  • Aggregate calculation: Handle None values when summing layer totals

Example format difference:

# Traditional Docker
{"progressDetail": {"current": 1234567, "total": 5000000}}

# Containerd snapshotter  
{"progressDetail": {"current": 32, "units": "s"}}  # total is None

Type of change

  • Bugfix (non-breaking change which fixes an issue)

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Ruff (ruff format supervisor tests)
  • Tests have been added to verify that the new code works.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Support Docker containerd snapshotter</issue_title>
<issue_description>### Description

Currently when using containerd snapshotter (e.g. can be enabled on HAOS 17 dev builds as mentioned in that comment home-assistant/operating-system#4360 (review)) Supervisor container image download progress processing raises errors like TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType':

2025-11-05 14:46:03.749 DEBUG (MainThread) [supervisor.bus] Fire event 'docker_image_pull_update' with 'PullLogEntry(job_id='96e947dfba2b4923936b304840f6e798', id='1444a2cdea29', status='Extracting', progress='9 s', progress_detail=PullProgressDetail(current=9, total=None), error=None)'
2025-11-05 14:46:03.749 ERROR (MainThread) [asyncio] Task exception was never retrieved
future: <Task finished name='Task-38680' coro=<DockerInterface.install.<locals>.process_pull_image_log() done, defined at /usr/src/supervisor/supervisor/docker/interface.py:404> exception=TypeError("unsupported operand type(s) for +=: 'int' and 'NoneType'")>
Traceback (most recent call last):
  File "/usr/src/supervisor/supervisor/docker/interface.py", line 406, in process_pull_image_log
    self._process_pull_image_log(curr_job_id, reference)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/supervisor/supervisor/docker/interface.py", line 345, in _process_pull_image_log
    total += job.extra["total"]
TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'

Additional context

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

@agners Unfortunately, that now means we can only tell per layer if it is not extracted/extracted, so the progress will be less smooth for the extracting part.

@sairon had the idea to use the per-layer size from the download operation. This way we can update the progress a bit more accurately.</comment_new>
<comment_new>@agners
Event log capture on a system with containerd snapshotter enabled:

import docker
client = docker.from_env()
log = client.api.pull("ghcr.io/home-assistant/qemux86-64-homeassistant", tag="2025.12.0.dev202511060240")

ContainerdSnapshotterPullProgress.txt</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix error handling for Docker containerd snapshotter Support Docker containerd snapshotter extraction progress Nov 11, 2025
Copilot finished work on behalf of agners November 11, 2025 09:51
Copilot AI requested a review from agners November 11, 2025 09:51
@agners
Copy link
Member

agners commented Nov 11, 2025

Unfortunately, this seems not to work correctly, the progress jumps from 0 to 100 without intermittent updates:

2025-11-11 15:21:07.428 DEBUG (MainThread) [supervisor.bus] Fire event 'supervisor_job_start' with 'SupervisorJob(created=datetime.datetime(2025, 11, 11, 14, 21, 7, 428066, tzinfo=datetime.timezone.utc), uuid='c85113c1823d4424b3c7cbbde2b13e2a', name='docker_interface_install', reference='homeassistant', progress=0, 
stage=None, parent_id='a5ca3275f2bd4b7cb2b4fa07f52b6ac6', done=None, on_change=<bound method JobManager._on_job_change of <supervisor.jobs.JobManager object at 0x7f5a98d19160>>, internal=True, errors=[], release_event=None, extra=None, child_job_syncs=None, parent_job_syncs=[ParentJobSync(uuid='12456a9010584d3d9fee6
435cebe623c', starting_progress=0, progress_allocation=1.0)])'
...
2025-11-11 15:22:44.196 DEBUG (MainThread) [supervisor.bus] Fire event 'supervisor_job_end' with 'SupervisorJob(created=datetime.datetime(2025, 11, 11, 14, 21, 7, 428066, tzinfo=datetime.timezone.utc), uuid='c85113c1823d4424b3c7cbbde2b13e2a', name='docker_interface_install', reference='homeassistant', progress=100, 
stage=None, parent_id='a5ca3275f2bd4b7cb2b4fa07f52b6ac6', done=False, on_change=<bound method JobManager._on_job_change of <supervisor.jobs.JobManager object at 0x7f5a98d19160>>, internal=True, errors=[], release_event=None, extra=None, child_job_syncs=None, parent_job_syncs=[ParentJobSync(uuid='12456a9010584d3d9fee
6435cebe623c', starting_progress=0, progress_allocation=1.0)])'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Docker containerd snapshotter

2 participants