f69eb3f9eb
Add native CE detection of "a newer image is available" for running
containers, surfaced as a read-only HTTP endpoint and a containers-list
badge/column. No applying of updates (M3/M4), no auto-heal (M1).
Backend:
- New CE handler GET /docker/{id}/containers/{containerId}/image_status
backed by the existing zlib/CE digest engine
(images.NewClientWithRegistry + ContainerImageStatus). Honors nodeName,
authz, and routes registry calls through the credential store / SSRF
AllowList. Engine failures degrade to a 200 {Status:"error"} so the UI
stays graceful. Response shape: {Status, Message?}.
Frontend (CE-only, no isBE gating; the EE ImageStatus component is left
untouched):
- useContainerImageStatus TanStack Query hook (5min staleTime, no
refetch-on-focus; backend caches 24h) calling the non-proxied endpoint.
- UpdateStatusBadge component (own assets, neutral on skipped/error).
- "Update available" column in the containers datatable; one cached,
non-blocking query per visible row.
Tests: Go response-shape unit test; vitest for the badge (all statuses)
and the hook (url + nodeName query param via msw).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
|
|
import { ContainerImageStatusValue } from '../../queries/useContainerImageStatus';
|
|
|
|
import { UpdateStatusBadge } from './UpdateStatusBadge';
|
|
|
|
describe('UpdateStatusBadge', () => {
|
|
it('renders "Update available" when the image is outdated', () => {
|
|
render(<UpdateStatusBadge status="outdated" />);
|
|
|
|
expect(screen.getByText('Update available')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders an up-to-date indicator when the image is updated', () => {
|
|
render(<UpdateStatusBadge status="updated" />);
|
|
|
|
expect(screen.getByText('Up to date')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows a spinner while loading', () => {
|
|
render(<UpdateStatusBadge isLoading />);
|
|
|
|
expect(
|
|
screen.getByLabelText('Checking for image updates')
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it.each<ContainerImageStatusValue>([
|
|
'skipped',
|
|
'error',
|
|
'processing',
|
|
'preparing',
|
|
])('renders nothing for the neutral status "%s"', (status) => {
|
|
const { container } = render(<UpdateStatusBadge status={status} />);
|
|
|
|
expect(container).toBeEmptyDOMElement();
|
|
});
|
|
|
|
it('renders nothing when status is undefined and not loading', () => {
|
|
const { container } = render(<UpdateStatusBadge />);
|
|
|
|
expect(container).toBeEmptyDOMElement();
|
|
});
|
|
});
|