fix: apply deployment resource settings to Kubernetes workloads
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-07-15 14:28:36 +09:00
parent 1c240e895b
commit a80e6eab20
2 changed files with 96 additions and 2 deletions
+66 -1
View File
@@ -975,6 +975,7 @@ export class AppsService {
const imageTags = parseReleaseImageTags(release.imageTags); const imageTags = parseReleaseImageTags(release.imageTags);
const images = imageTags.images; const images = imageTags.images;
const requestedResources = body.resources;
const runtimeProfile = await this.prisma.runtimeEnvProfile.findFirst({ const runtimeProfile = await this.prisma.runtimeEnvProfile.findFirst({
where: { where: {
appId: release.appId, appId: release.appId,
@@ -1053,14 +1054,25 @@ export class AppsService {
deploymentName, deploymentName,
componentName, componentName,
image, image,
replicas: component?.replicas ?? 1, replicas: requestedResources?.replicas ?? component?.replicas ?? 1,
ports: getComponentPorts(component), ports: getComponentPorts(component),
resources: requestedResources,
}) })
), ),
); );
} }
const workloadRef = `${workloadType.toLowerCase()}/${deploymentName}`; const workloadRef = `${workloadType.toLowerCase()}/${deploymentName}`;
if (requestedResources?.replicas) {
logs.push(`[scale] ${workloadRef} replicas=${requestedResources.replicas}`);
appendOutput(logs, await this.kubectl([
'scale',
workloadRef,
`--replicas=${requestedResources.replicas}`,
'-n',
namespace,
]));
}
logs.push(`[set-image] ${workloadRef} ${deploymentName}=${image}`); logs.push(`[set-image] ${workloadRef} ${deploymentName}=${image}`);
const setImageOutput = await this.kubectl([ const setImageOutput = await this.kubectl([
'set', 'set',
@@ -1072,6 +1084,31 @@ export class AppsService {
]); ]);
appendOutput(logs, setImageOutput); appendOutput(logs, setImageOutput);
const resourceArgs = [
'set',
'resources',
workloadRef,
`--containers=${deploymentName}`,
'-n',
namespace,
...(requestedResources?.cpuRequest || requestedResources?.memoryRequest
? [`--requests=${[
requestedResources.cpuRequest ? `cpu=${requestedResources.cpuRequest}` : null,
requestedResources.memoryRequest ? `memory=${requestedResources.memoryRequest}` : null,
].filter(Boolean).join(',')}`]
: []),
...(requestedResources?.cpuLimit || requestedResources?.memoryLimit
? [`--limits=${[
requestedResources.cpuLimit ? `cpu=${requestedResources.cpuLimit}` : null,
requestedResources.memoryLimit ? `memory=${requestedResources.memoryLimit}` : null,
].filter(Boolean).join(',')}`]
: []),
];
if (resourceArgs.length > 6) {
logs.push(`[resources] ${workloadRef}`);
appendOutput(logs, await this.kubectl(resourceArgs));
}
logs.push(`[rollout] ${workloadRef}`); logs.push(`[rollout] ${workloadRef}`);
const rolloutOutput = await this.kubectl([ const rolloutOutput = await this.kubectl([
'rollout', 'rollout',
@@ -2814,6 +2851,12 @@ function createDeploymentManifest(input: {
image: string; image: string;
replicas?: number | null; replicas?: number | null;
ports?: ComponentPort[]; ports?: ComponentPort[];
resources?: {
cpuRequest?: string;
cpuLimit?: string;
memoryRequest?: string;
memoryLimit?: string;
};
}) { }) {
const labels = { const labels = {
'app.kubernetes.io/name': input.deploymentName, 'app.kubernetes.io/name': input.deploymentName,
@@ -2846,6 +2889,28 @@ function createDeploymentManifest(input: {
name: input.deploymentName, name: input.deploymentName,
image: input.image, image: input.image,
imagePullPolicy: 'IfNotPresent', imagePullPolicy: 'IfNotPresent',
...(input.resources?.cpuRequest || input.resources?.memoryRequest || input.resources?.cpuLimit || input.resources?.memoryLimit
? {
resources: {
...(input.resources.cpuRequest || input.resources.memoryRequest
? {
requests: {
...(input.resources.cpuRequest ? { cpu: input.resources.cpuRequest } : {}),
...(input.resources.memoryRequest ? { memory: input.resources.memoryRequest } : {}),
},
}
: {}),
...(input.resources.cpuLimit || input.resources.memoryLimit
? {
limits: {
...(input.resources.cpuLimit ? { cpu: input.resources.cpuLimit } : {}),
...(input.resources.memoryLimit ? { memory: input.resources.memoryLimit } : {}),
},
}
: {}),
},
}
: {}),
...(input.ports?.length ...(input.ports?.length
? { ? {
ports: input.ports.map((port) => ({ ports: input.ports.map((port) => ({
+30 -1
View File
@@ -1,4 +1,5 @@
import { ArrayNotEmpty, IsArray, IsBoolean, IsEnum, IsInt, IsOptional, IsString, IsUUID, Min } from 'class-validator'; import { Type } from 'class-transformer';
import { ArrayNotEmpty, IsArray, IsBoolean, IsEnum, IsInt, IsOptional, IsString, IsUUID, Min, ValidateNested } from 'class-validator';
import { AppStatus, ComponentType } from './app-enums'; import { AppStatus, ComponentType } from './app-enums';
export class CreateAppDto { export class CreateAppDto {
@@ -195,6 +196,29 @@ export class CreateAppReleaseDto {
buildJobIds!: string[]; buildJobIds!: string[];
} }
export class DeploymentResourceLimitsDto {
@IsOptional()
@Type(() => Number)
@IsInt()
replicas?: number;
@IsOptional()
@IsString()
cpuRequest?: string;
@IsOptional()
@IsString()
cpuLimit?: string;
@IsOptional()
@IsString()
memoryRequest?: string;
@IsOptional()
@IsString()
memoryLimit?: string;
}
export class CreateDeploymentJobDto { export class CreateDeploymentJobDto {
@IsUUID() @IsUUID()
releaseId!: string; releaseId!: string;
@@ -208,6 +232,11 @@ export class CreateDeploymentJobDto {
@IsOptional() @IsOptional()
@IsBoolean() @IsBoolean()
updateLauncherAppVersion?: boolean; updateLauncherAppVersion?: boolean;
@IsOptional()
@ValidateNested()
@Type(() => DeploymentResourceLimitsDto)
resources?: DeploymentResourceLimitsDto;
} }
export class CreateRuntimeEnvProfileDto { export class CreateRuntimeEnvProfileDto {