Skip to content

Conversation

Copy link

Copilot AI commented Nov 10, 2025

Adds resumable download support to handle interrupted model pulls. On retry, the system checks for .incomplete files, verifies server Range request support via Accept-Ranges header, and resumes from the last byte position. Falls back to full download if Range not supported. Includes retry logic (3 attempts, exponential backoff: 1s→2s→4s).

Changes

go-containerregistry fetcher (pkg/go-containerregistry/pkg/v1/remote/)

  • Added fetchBlobWithOffset(offset) to send Range: bytes={offset}- headers
  • Added supportsRangeRequests() to detect server capability via HEAD request
  • Skip hash verification for partial content (206 responses) since incomplete data can't be validated
  • Extended remoteLayer with CompressedWithOffset() and SupportsRangeRequests() methods
  • Propagated resumable methods through MountableLayer wrapper

Store resumable orchestration (pkg/distribution/internal/store/blobs.go)

  • Added ResumableBlob interface and writeBlobResumable() with:
    • .incomplete file detection and size check
    • Server Range support verification before resume attempt
    • Offset-based download continuation or full redownload fallback
    • Exponential backoff retry (max 3 attempts)
  • Modified writeLayer() to detect and use resumable layers via type assertion

Example Flow

// Store detects incomplete file
if info, err := os.Stat(incompletePath); err == nil {
    offset = info.Size()
    
    // Check server capability
    if supportsRange, _ := layer.SupportsRangeRequests(); supportsRange {
        // Resume from offset
        rc, _ := layer.CompressedWithOffset(offset)
    } else {
        // Full download fallback
        os.Remove(incompletePath)
    }
}

Maintains full backward compatibility with existing non-resumable download paths.

Original prompt

Implement resumable downloads for "model-cli pull", implement in pkg/go-containerregistry/ , if all processes die it should be able to:

On next attempt, the system:
- Checks for .incomplete file and gets its size
- Check if the server supports range requests
- If it does, sends the HTTP Range request: Range: bytes={size}-, appends new data to existing file, else download from scratch as the server doesn't support Range requests.
- Retries up to 3 times with exponential backoff


💡 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] Add resumable downloads for model-cli pull Implement resumable downloads with HTTP Range requests for model-cli pull Nov 10, 2025
Copilot AI requested a review from ericcurtin November 10, 2025 15:28
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.

2 participants