portainer/app/react/docker/images/queries/useBuildImageMutation.ts

286 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import axios, {
jsonObjectsToArrayHandler,
parseAxiosError,
} from '@/portainer/services/axios';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { buildDockerProxyUrl } from '../../proxy/queries/buildDockerProxyUrl';
import { formatArrayQueryParamsForDockerAPI } from '../../proxy/queries/utils';
export async function buildImageFromUpload(
environmentId: EnvironmentId,
names: string[],
file: File,
path: string
) {
return buildImage(
environmentId,
{ t: names, dockerfile: path },
file,
file.type
);
}
export async function buildImageFromURL(
environmentId: EnvironmentId,
names: string[],
url: string,
path: string
) {
return buildImage(
environmentId,
{ t: names, remote: url, dockerfile: path },
{},
'application/x-tar'
);
}
export async function buildImageFromDockerfileContent(
environmentId: EnvironmentId,
names: string[],
content: string
) {
return buildImage(
environmentId,
{ t: names },
{ content },
'application/json'
);
}
export async function buildImageFromDockerfileContentAndFiles(
environmentId: EnvironmentId,
names: string[],
content: string,
files: File[]
) {
const dockerfile = new Blob([content], { type: 'text/plain' });
const uploadFiles = [dockerfile, ...files];
return buildImage(
environmentId,
{ t: names },
{ file: uploadFiles },
'multipart/form-data'
);
}
/**
* Raw docker API proxy
*
* -----
*
* See api/http/proxy/factory/docker/build.go for the rules (copied below)
*
* buildOperation inspects the "Content-Type" header to determine if it needs to alter the request.
*
* -- buildImageFromUpload()
* If the value of the header is empty, it means that a Dockerfile is posted via upload, the function
* will extract the file content from the request body, tar it, and rewrite the body.
* !! THIS IS ONLY TRUE WHEN THE UPLOADED DOCKERFILE FILE HAS NO EXTENSION (the generated file.type in the frontend will be empty)
* If the Dockerfile is named like Dockerfile.yaml or has an internal type, a non-empty Content-Type header will be generated
*
* -- buildImageFromDockerfileContent()
* If the value of the header contains "application/json", it means that the content of a Dockerfile is posted
* in the request payload as JSON, the function will create a new file called Dockerfile inside a tar archive and
* rewrite the body of the request.
*
* -- buildImageFromUpload()
* -- buildImageFromURL()
* -- buildImageFromDockerfileContentAndFiles()
* In any other case, it will leave the request unaltered.
*
* -----
*
* @param environmentId
* @param params
* @param payload
* @param contentType
*/
async function buildImage(
environmentId: EnvironmentId,
params: BuildImageQueryParams,
payload: unknown,
contentType: string
) {
try {
const { data } = await axios.post(
buildDockerProxyUrl(environmentId, 'build'),
payload,
{
headers: { 'Content-Type': contentType },
params,
transformResponse: jsonObjectsToArrayHandler,
paramsSerializer: formatArrayQueryParamsForDockerAPI,
}
);
return data;
} catch (err) {
throw parseAxiosError(err, 'Unable to build image');
}
}
type BuildImageQueryParams = {
/**
* Path within the build context to the Dockerfile.
* This is ignored if remote is specified and points to an external Dockerfile.
*
* @default "Dockerfile"
*/
dockerfile?: string;
/**
* A name and optional tag to apply to the image in the name:tag format.
* If you omit the tag the default latest value is assumed.
* You can provide several t parameters.
*/
t?: string[];
/**
* Extra hosts to add to /etc/hosts
*/
extrahost?: string;
/**
* A Git repository URI or HTTP/HTTPS context URI.
* If the URI points to a single text file, the files contents are placed into a file called Dockerfile and the image is built from that file.
* If the URI points to a tarball, the file is downloaded by the daemon and the contents therein used as the context for the build.
* If the URI points to a tarball and the dockerfile parameter is also specified, there must be a file with the corresponding path inside the tarball.
*/
remote?: string;
/**
* Suppress verbose build output.
*
* @default false
*/
q?: boolean;
/**
* Do not use the cache when building the image.
*
* @default false
*/
nocache?: boolean;
/**
* JSON array of images used for build cache resolution.
*/
cachefrom?: string[];
/**
* Attempt to pull the image even if an older image exists locally.
*/
pull?: string;
/**
* Remove intermediate containers after a successful build.
*
* @default true
*/
rm?: boolean;
/**
* Always remove intermediate containers, even upon failure.
*
* @default false
*/
forcerm?: boolean;
/**
* Set memory limit for build.
*/
memory?: number;
/**
* Total memory (memory + swap).
*
* Set as -1 to disable swap.
*/
memswap?: number;
/**
* CPU shares (relative weight).
*/
cpushares?: number;
/**
* CPUs in which to allow execution (e.g., 0-3, 0,1).
*/
cpusetcpus?: string;
/**
* The length of a CPU period in microseconds.
*/
cpuperiod?: number;
/**
* Microseconds of CPU time that the container can get in a CPU period.
*/
cpuquota?: number;
/**
* JSON map of string pairs for build-time variables. Users pass these values at build-time.
* Docker uses the buildargs as the environment context for commands run via the Dockerfile RUN instruction, or for variable expansion in other Dockerfile instructions.
* This is not meant for passing secret values.
* For example, the build arg FOO=bar would become {"FOO":"bar"} in JSON. This would result in the query parameter buildargs={"FOO":"bar"}.
* Note that {"FOO":"bar"} should be URI component encoded.
* Read more about the buildargs instruction.
*/
buildargs?: string;
/**
* Size of /dev/shm in bytes. The size must be greater than 0. If omitted the system uses 64MB.
*/
shmsize?: number;
/**
* Squash the resulting images layers into a single layer. (Experimental release only.)
*/
squash?: boolean;
/**
* Arbitrary key/value labels to set on the image, as a JSON map of string pairs.
*/
labels?: Record<string, string>;
/**
* Sets the networking mode for the run commands during build. Supported standard values are: bridge, host, none, and container:<name|id>.
* Any other value is taken as a custom network's name or ID to which this container should connect to.
*/
networkmode?: string;
/**
* Platform in the format os[/arch[/variant]]
*
* @default ""
*/
platform?: string;
/**
* Target build stage
*
* @default ""
*/
target?: string;
/**
* BuildKit output configuration
*
* @default ""
*/
outputs?: string;
/**
* Version of the builder backend to use.
*
* @enum {('1' | '2')}
*
* @default '1'
*
* - 1 is the first generation classic (deprecated) builder in the Docker daemon (default)
* - 2 is BuildKit
*/
version?: string;
};