Skip to content

Add Registry Ping Command#45

Merged
toddysm merged 9 commits into
mainfrom
feature/ping
Mar 14, 2026
Merged

Add Registry Ping Command#45
toddysm merged 9 commits into
mainfrom
feature/ping

Conversation

@toddysm
Copy link
Copy Markdown
Owner

@toddysm toddysm commented Mar 14, 2026

Summary

Implements regshape ping --registry <host> command that checks OCI registry connectivity by issuing GET /v2/ per the OCI Distribution Spec. Closes #32.

Changes

Library Layer (src/regshape/libs/ping/)

  • operations.py: ping(client) -> PingResult function that:
    • Issues GET /v2/ via RegistryClient and measures round-trip latency
    • Returns PingResult dataclass with reachable, status_code, api_version (from Docker-Distribution-API-Version header), and latency_ms
    • Raises PingError on connection, DNS, or timeout failures
    • Raises AuthError on HTTP 401 responses
  • __init__.py: Re-exports ping and PingResult

CLI Layer (src/regshape/cli/ping.py)

  • Top-level ping command registered directly on the regshape group
  • Options: --registry/-r (required), --json (flag)
  • Auth errors (401/403 token negotiation) are treated as reachable, since the registry responded with a challenge proving connectivity. Output includes a hint to run regshape auth login.
  • Exit code 0 on reachable (including auth-required), exit code 1 on unreachable

Other Changes

  • PingError added to src/regshape/libs/errors.py
  • ping command registered in src/regshape/cli/main.py
  • Design spec at specs/cli/ping.md

Usage

# Basic ping
regshape ping --registry ghcr.io

# JSON output
regshape ping --registry ghcr.io --json

# Insecure (HTTP) registry
regshape --insecure ping --registry localhost:5000

Example Output

Registry ghcr.io is reachable
  Note: Registry requires authentication. Run 'regshape auth login' to configure credentials.
{
  "reachable": true,
  "status_code": 200,
  "api_version": "registry/2.0",
  "latency_ms": 42.3,
  "registry": "ghcr.io"
}

Tests

23 unit tests added:

  • test_ping_operations.py (11 tests): PingResult serialization, success with/without API version header, non-200 responses, 401 auth error, connection/timeout/generic errors, latency measurement
  • test_ping_cli.py (12 tests): plain text and JSON output, exit codes, auth error handling, insecure flag propagation, required option validation

toddysm added 2 commits March 13, 2026 17:45
Add 'regshape ping --registry <host>' command that issues GET /v2/ to
verify registry connectivity and OCI Distribution API support.

Library layer (libs/ping/):
- ping() function issues GET /v2/ via RegistryClient, measures latency,
  and returns a PingResult dataclass with reachable, status_code,
  api_version (Docker-Distribution-API-Version header), and latency_ms
- Raises PingError on connection/DNS/timeout failures
- Raises AuthError on HTTP 401 responses

CLI layer (cli/ping.py):
- Top-level 'ping' command (not a subcommand group)
- --registry/-r (required): registry hostname
- --json: JSON output format
- Auth errors treated as reachable (registry responded with 401 challenge)
  with a hint to run 'regshape auth login'
- Exit code 0 on success/auth-required, 1 on unreachable

Other changes:
- Add PingError to libs/errors.py
- Register ping command in cli/main.py
- 23 unit tests (11 operations + 12 CLI)
Copilot AI review requested due to automatic review settings March 14, 2026 01:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new top-level regshape ping command to validate OCI registry connectivity via GET /v2/, implemented with a small library operation layer and covered by new unit tests/spec documentation.

Changes:

  • Introduces regshape.libs.ping with ping(client) and a PingResult model (latency + API version header support).
  • Adds regshape ping --registry ... [--json] CLI command and registers it in the main CLI.
  • Adds PingError and new unit tests + a design/spec document for the command.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/regshape/libs/ping/operations.py Implements library-level ping and PingResult serialization.
src/regshape/libs/ping/init.py Re-exports ping API surface.
src/regshape/libs/errors.py Adds PingError to shared error types.
src/regshape/cli/ping.py Implements the Click command, JSON/plain output, and exit codes.
src/regshape/cli/main.py Registers the new top-level ping command.
src/regshape/tests/test_ping_operations.py Unit tests for ping operation behavior and serialization.
src/regshape/tests/test_ping_cli.py CLI tests for output modes, exit codes, and flag propagation.
specs/cli/ping.md Command design/spec and examples/test plan.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread specs/cli/ping.md Outdated
Comment thread specs/cli/ping.md Outdated
Comment thread src/regshape/cli/ping.py
Comment thread src/regshape/cli/ping.py
Comment thread src/regshape/cli/ping.py Outdated
Comment thread src/regshape/tests/test_ping_operations.py Outdated
Comment thread specs/cli/ping.md Outdated
toddysm and others added 7 commits March 13, 2026 18:20
The Exit Codes section says code 0 means only HTTP 200, but the CLI behavior described in this PR (and implemented in src/regshape/cli/ping.py) treats auth-required as reachable and exits 0 as well. Please update this table/description to include the auth-required reachable case so the spec matches the implementation.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
The CLI test plan here says Auth failure → exit code 1, but the implemented CLI/tests treat AuthError as reachable and exit 0 (see TestPingCommand.test_auth_error_exits_0_reachable). Please reconcile the spec with the intended behavior (either update the plan or adjust the CLI/tests).

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
When handling PingError, passing str(exc) into _error() results in duplicated messaging because PingError messages already include Registry <host> is not reachable. This currently produces output like Error: Registry <host> is not reachable: Registry <host> is not reachable : <reason>. Consider using the underlying exception (exc.__cause__) or changing PingError to carry/format only the low-level reason so the CLI can add the prefix once.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
For --json, the unreachable (non-200) path calls _error() which emits only {registry, reachable, error} and discards the structured fields you already have in PingResult (status_code, api_version, latency_ms). This diverges from the PR description/spec examples and makes the JSON output harder to consume programmatically. Consider returning a JSON object that includes at least status_code and latency_ms (and api_version if present) for non-200 responses, rather than collapsing everything into an error string.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
In the AuthError JSON output you hardcode "status_code": 401, but AuthError can be raised for cases that aren't strictly an HTTP 401 (e.g. Basic auth required but no credentials, token negotiation failures that surface as 403, etc.). If you can't reliably surface a status code here, it would be more accurate to omit it / set it to null and include error/note text from the exception, or extend AuthError to optionally carry an HTTP status code similar to BlobError.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
Unused import: patch is imported from unittest.mock but never used in this test module. This can trigger lint failures and adds noise—please remove it.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
The documented JSON failure format shows status_code/api_version/latency_ms fields, but the current CLI implementation (_error() in src/regshape/cli/ping.py) emits {registry, reachable, error} for failures. Either update this spec example to match the actual output, or update the CLI to include those structured fields on non-200 responses.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Toddy Mladenov <me@toddysm.com>
@toddysm toddysm merged commit ede4c84 into main Mar 14, 2026
3 checks passed
@toddysm toddysm deleted the feature/ping branch March 14, 2026 16:51
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.

Add Registry Ping Command

2 participants