Files

82 lines
2.2 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios/axios';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { Registry } from '@/react/portainer/registries/types/registry';
import { useEnvironmentRegistries } from '@/react/portainer/environments/queries/useEnvironmentRegistries';
import { withError, withInvalidate } from '@/react-tools/react-query';
import { buildImageFullURI } from '../utils';
import {
withRegistryAuthHeader,
withAgentTargetHeader,
} from '../../proxy/queries/utils';
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
import { queryKeys } from './queryKeys';
type UsePullImageMutation = Omit<PullImageOptions, 'registry'> & {
registryId?: Registry['Id'];
};
export function usePullImageMutation(envId: EnvironmentId) {
const queryClient = useQueryClient();
const registriesQuery = useEnvironmentRegistries(envId);
return useMutation({
mutationFn: (args: UsePullImageMutation) =>
pullImage({
...args,
registry: getRegistry(registriesQuery.data || [], args.registryId),
}),
...withError('Failure', 'Failed pulling image'),
...withInvalidate(queryClient, [queryKeys.base(envId)]),
});
}
function getRegistry(registries: Registry[], registryId?: Registry['Id']) {
return registryId
? registries.find((registry) => registry.Id === registryId)
: undefined;
}
interface PullImageOptions {
environmentId: EnvironmentId;
image: string;
nodeName?: string;
registry?: Registry;
ignoreErrors: boolean;
}
export async function pullImage({
environmentId,
ignoreErrors,
image,
nodeName,
registry,
}: PullImageOptions) {
const imageURI = buildImageFullURI(image, registry);
try {
await axios.post(
buildDockerProxyUrl(environmentId, 'images', 'create'),
null,
{
params: {
fromImage: imageURI,
},
headers: {
...withRegistryAuthHeader(registry?.Id),
...withAgentTargetHeader(nodeName),
},
}
);
} catch (err) {
if (ignoreErrors) {
return;
}
throw parseAxiosError(err, 'Unable to pull image');
}
}