1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-04 21:35:23 +02:00

feat(podman): support add podman envs in the wizard [r8s-20] (#12056)
Some checks failed
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
ci / build_images (map[arch:arm platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Has been cancelled
/ triage (push) Has been cancelled
Lint / Run linters (push) Has been cancelled
Test / test-client (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:linux]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
Test / test-server (map[arch:arm64 platform:linux]) (push) Has been cancelled
ci / build_manifests (push) Has been cancelled

This commit is contained in:
Ali 2024-09-25 11:55:07 +12:00 committed by GitHub
parent db616bc8a5
commit 32e94d4e4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
108 changed files with 1921 additions and 272 deletions

View file

@ -73,11 +73,11 @@ function Cell({
});
return (
<>
<div className="flex gap-1">
<a href={linkProps.href} onClick={linkProps.onClick} title={name}>
{truncate(name, 40)}
</a>
{!image.used && <UnusedBadge />}
</>
</div>
);
}

View file

@ -2,6 +2,8 @@ import { CellContext } from '@tanstack/react-table';
import { ImagesListResponse } from '@/react/docker/images/queries/useImages';
import { Badge } from '@@/Badge';
import { columnHelper } from './helper';
export const tags = columnHelper.accessor((item) => item.tags?.join(','), {
@ -16,12 +18,12 @@ function Cell({
const repoTags = item.tags;
return (
<>
<div className="flex flex-wrap gap-1">
{repoTags?.map((tag, idx) => (
<span key={idx} className="label label-primary image-tag" title={tag}>
<Badge key={idx} type="info">
{tag}
</span>
</Badge>
))}
</>
</div>
);
}

View file

@ -0,0 +1,51 @@
import { describe, it, expect } from 'vitest';
import { fullURIIntoRepoAndTag } from './utils';
describe('fullURIIntoRepoAndTag', () => {
it('splits registry/image-repo:tag correctly', () => {
const result = fullURIIntoRepoAndTag('registry.example.com/my-image:v1.0');
expect(result).toEqual({
repo: 'registry.example.com/my-image',
tag: 'v1.0',
});
});
it('splits image-repo:tag correctly', () => {
const result = fullURIIntoRepoAndTag('nginx:latest');
expect(result).toEqual({ repo: 'nginx', tag: 'latest' });
});
it('splits registry:port/image-repo:tag correctly', () => {
const result = fullURIIntoRepoAndTag(
'registry.example.com:5000/my-image:v2.1'
);
expect(result).toEqual({
repo: 'registry.example.com:5000/my-image',
tag: 'v2.1',
});
});
it('handles empty string input', () => {
const result = fullURIIntoRepoAndTag('');
expect(result).toEqual({ repo: '', tag: 'latest' });
});
it('handles input with multiple colons', () => {
const result = fullURIIntoRepoAndTag('registry:5000/namespace/image:v1.0');
expect(result).toEqual({
repo: 'registry:5000/namespace/image',
tag: 'v1.0',
});
});
it('handles input with @ symbol (digest)', () => {
const result = fullURIIntoRepoAndTag(
'myregistry.azurecr.io/image@sha256:123456'
);
expect(result).toEqual({
repo: 'myregistry.azurecr.io/image@sha256',
tag: '123456',
});
});
});

View file

@ -9,6 +9,12 @@ import {
import { DockerImage } from './types';
import { DockerImageResponse } from './types/response';
type ImageModel = {
UseRegistry: boolean;
Registry?: Registry;
Image: string;
};
export function parseViewModel(response: DockerImageResponse): DockerImage {
return {
...response,
@ -40,11 +46,7 @@ export function imageContainsURL(image: string) {
return false;
}
export function buildImageFullURIFromModel(imageModel: {
UseRegistry: boolean;
Registry?: Registry;
Image: string;
}) {
export function buildImageFullURIFromModel(imageModel: ImageModel) {
const registry = imageModel.UseRegistry ? imageModel.Registry : undefined;
return buildImageFullURI(imageModel.Image, registry);
}
@ -107,3 +109,24 @@ function buildImageFullURIWithRegistry(image: string, registry: Registry) {
return url + image;
}
}
/**
* Splits a full URI into repository and tag.
*
* @param fullURI - The full URI to be split.
* @returns An object containing the repository and tag.
*/
export function fullURIIntoRepoAndTag(fullURI: string) {
// possible fullURI values (all should contain a tag):
// - registry/image-repo:tag
// - image-repo:tag
// - registry:port/image-repo:tag
// buildImageFullURIFromModel always gives a tag (defaulting to 'latest'), so the tag is always present after the last ':'
const parts = fullURI.split(':');
const tag = parts.pop() || 'latest';
const repo = parts.join(':');
return {
repo,
tag,
};
}