feat(registries): add exact-ID tag browser with non-401 failures (#1613)

* feat(resources): show multi-stack usedByStacks on images

Classify images with a deduped sorted stack reverse index, surface chips in the Images table and inspect sheet, and clear node-bound sheet selection on active-node change.

* feat(registries): add exact-ID tag browser with non-401 failures

Add GET /api/registries/:id/tags using credentials for that registry row only, map upstream auth failures to 424, and surface a Registry tags section on the image inspect sheet.

* fix(registries): distinguish unreachable hosts from auth failures

Map auth transport errors to REGISTRY_UPSTREAM (502), surface registry list-load failures in the tag panel, document Used by and Registry tags, and add parser coverage.

* fix(registries): drop unused RegistryTagsPanel __test export

The non-component export tripped react-refresh/only-export-components and failed Frontend lint in CI.
This commit is contained in:
Anso
2026-07-11 13:21:38 -04:00
committed by GitHub
parent 362a18e91a
commit ce699864c1
12 changed files with 977 additions and 76 deletions
+8
View File
@@ -25,6 +25,14 @@ Sencho stores credentials for your private Docker registries and injects them au
AWS ECR requires a Sencho **Admiral** license; Docker Hub, GHCR, and custom registries are available on every tier.
## Browse tags from Resources
When you inspect an image on the Resources page, the detail sheet includes a **Registry tags** section for admins. Sencho lists tags from the configured registry that matches the image host (credentials come from that registry row only). Tag browsing always runs on the hub instance; local image digests still come from the active node.
If credentials are wrong, Sencho reports a registry error without signing you out of the dashboard.
## Where to find it
Open **Settings → Infrastructure → Registries** on the Sencho instance you are signed into directly. The section is hidden when you are viewing another node through the node switcher.
+5 -3
View File
@@ -83,13 +83,15 @@ Lists all Docker images on the host with their ID, repository tag, size, and sta
#### Inspect image
Click the eye icon on any image row to open a detail sheet with three sections:
Click the eye icon on any image row to open a detail sheet with these sections:
- **Overview** lists the ID, size, creation date, architecture and OS, author, all repository tags, and which Sencho stacks use the image.
- **Used by** lists every Sencho stack that references the image (chips open that stack). Sourced from the Resources inventory, so it stays visible while inspect loads or if inspect fails.
- **Overview** lists the ID, size, creation date, architecture and OS, author, and all repository tags.
- **Config** shows the default `Cmd`, `Entrypoint`, `WorkingDir`, `User`, exposed ports, environment variables, and labels. Env vars and labels are collapsible.
- **Layers** lists the layer history in build order. Each row shows the layer index, size, age, and the build command (`CreatedBy`). Empty layers (metadata-only, zero bytes) are dimmed.
- **Registry tags** (admins) lists remote tags from a matching configured registry. See [Private registries](/features/private-registries) for credential and failure behavior.
The inspect sheet is read-only and available to all roles.
The inspect sheet is available to all roles. Registry tag browsing is admin-only.
### Volumes
+61
View File
@@ -644,6 +644,26 @@ components:
description: Required when `type` is `ecr`.
example: us-east-1
RegistryTagList:
type: object
required: [tags, nextCursor, registryId, registryName, repository]
properties:
tags:
type: array
items: { type: string }
example: [latest, "1.0"]
nextCursor:
type: ["string", "null"]
description: Opaque cursor for the next page, or null when there are no more tags.
registryId:
type: integer
registryName:
type: string
repository:
type: string
description: Path-safe repository name after Docker Hub library/ normalization when applicable.
example: library/nginx
ImageUpdateStatus:
type: object
properties:
@@ -3605,3 +3625,44 @@ paths:
$ref: "#/components/responses/Unauthorized"
"403":
description: Non-admin users cannot change the schedule.
/api/registries/{id}/tags:
get:
tags: [Registries]
summary: List tags for a repository on a configured registry
description: |
Hub-only. Admin only. Credentials are resolved by exact registry ID.
Upstream registry auth failures return 424 with a REGISTRY_* code, never HTTP 401.
parameters:
- name: id
in: path
required: true
schema: { type: integer }
- name: repository
in: query
required: true
schema: { type: string }
description: Path-safe repository name (no host or scheme)
- name: cursor
in: query
required: false
schema: { type: string }
- name: limit
in: query
required: false
schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
responses:
'200':
description: Tag page
content:
application/json:
schema:
$ref: "#/components/schemas/RegistryTagList"
'400':
description: Invalid repository or response
'404':
description: Registry or repository not found
'424':
description: Upstream registry auth or policy failure (not a Sencho session 401)
'502':
description: Upstream registry transport failure