Skip to content

Commit

Permalink
add imagebuilder resource override
Browse files Browse the repository at this point in the history
  • Loading branch information
leonlnj committed Dec 7, 2023
1 parent 2856fe7 commit 2d1e720
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 8 deletions.
8 changes: 3 additions & 5 deletions api/pkg/imagebuilder/imagebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,18 +485,16 @@ func (c *imageBuilder) createKanikoJobSpec(
cpuLimit := resource.MustParse(c.config.DefaultResources.Limits.CPU)
memoryLimit := resource.MustParse(c.config.DefaultResources.Limits.Memory)

// User defined resource request and limit will override the default value
// User defined resource request and limit will override the default value and set request==limit
if resourceRequest != nil {
if !resourceRequest.CPURequest.IsZero() {
cpuRequest = resourceRequest.CPURequest
cpuLimit = resourceRequest.CPURequest
}
if !resourceRequest.MemoryRequest.IsZero() {
memoryRequest = resourceRequest.MemoryRequest
memoryLimit = resourceRequest.MemoryRequest
}

// If user overide the request, we also override the limit == request
cpuLimit = resourceRequest.CPURequest
memoryLimit = resourceRequest.MemoryRequest
}

resourceRequirements = RequestLimitResources{
Expand Down
12 changes: 11 additions & 1 deletion ui/src/job/form/JobFormOthers.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ import { ServiceAccountSelect } from "./components/ServiceAccountSelect";
import { ResourceRequestForm } from "./components/ResourceRequestForm";
import { EnvironmentVariablesForm } from "./components/EnvironmentVariablesForm";
import PropTypes from "prop-types";
import { ImageBuilderSection } from "../../pages/version/components/forms/components/ImageBuilderSection";
import { useOnChangeHandler } from "@caraml-dev/ui-lib";

export const JobFormOthers = ({ versions, isSelectVersionDisabled }) => {
const {
job,
setVersionId,
setServiceAccountName,
setResourceRequest,
setEnvVars
setEnvVars,
onChangeHandler
} = useContext(JobFormContext);
const { onChange } = useOnChangeHandler(onChangeHandler);

return (
<Fragment>
Expand Down Expand Up @@ -75,6 +79,12 @@ export const JobFormOthers = ({ versions, isSelectVersionDisabled }) => {
/>
</EuiFlexItem>
</EuiFlexGroup>

<EuiSpacer size="l" />
<ImageBuilderSection
imageBuilderResourceConfig={job.config.image_builder_resource_request}
onChangeHandler={onChange("config.image_builder_resource_request")}
/>
</Fragment>
);
};
Expand Down
25 changes: 24 additions & 1 deletion ui/src/job/form/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import React, { useCallback, useState } from "react";
import PropTypes from "prop-types";
import { StackableFunction, set, useOnChangeHandler } from "@caraml-dev/ui-lib";

export const JobFormContext = React.createContext({});

Expand Down Expand Up @@ -209,6 +210,26 @@ export const JobFormContextProvider = ({ job: initJob, ...props }) => {
},
[setJob]
);

// This port partial of the FormContextProvider that most of the forms are using,
// so that the similiar/future section using onChangeHandler can be reused and
// does not requires adding new callbacks per field
var handleChanges = React.useCallback(function (paths, value) {
var path = paths.filter(function (part) {
return !!part;
}).join(".");
setJob(function (data) {
set(data, path, value);
return Object.assign(Object.create(data), data);
});
}, [setJob]);
var rootHandler = React.useMemo(function () {
return new StackableFunction([], handleChanges);
}, [handleChanges]);

var _useOnChangeHandler = useOnChangeHandler(rootHandler),
onChangeHandler = _useOnChangeHandler.onChangeHandler,
onChange = _useOnChangeHandler.onChange;

return (
<JobFormContext.Provider
Expand All @@ -224,7 +245,9 @@ export const JobFormContextProvider = ({ job: initJob, ...props }) => {
unsetBigquerySourceOptions,
setBigquerySink,
setBigquerySinkOptions,
setEnvVars
setEnvVars,
onChange: onChange,
onChangeHandler: onChangeHandler
}}>
{props.children}
</JobFormContext.Provider>
Expand Down
4 changes: 4 additions & 0 deletions ui/src/job/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class Job {
service_account_name: "",

resource_request: {},
image_builder_resource_request: {
cpu_request: "",
memory_request: ""
},

env_vars: [],

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { FormLabelWithToolTip, useOnChangeHandler } from "@caraml-dev/ui-lib";
import {
EuiAccordion,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
EuiFormRow,
EuiSpacer
} from "@elastic/eui";


export const ImageBuilderSection = ({
imageBuilderResourceConfig,
onChangeHandler,
errors = {},
}) => {

const { onChange } = useOnChangeHandler(onChangeHandler);

return (
<EuiAccordion
id="imagebuilderOption"
buttonContent="Advanced configurations">
<EuiSpacer size="s" />
<EuiFlexGroup direction="row">
<EuiFlexItem>
<EuiFormRow
label={
<FormLabelWithToolTip
label="Image Builder CPU *"
content="To set a higher CPU above platform default for Image Building"
/>
}
isInvalid={!!errors.cpu_request}
error={errors.cpu_request}
fullWidth
>
<EuiFieldText
placeholder="500m"
value={imageBuilderResourceConfig.cpu_request}
onChange={(e) => onChange("cpu_request")(e.target.value)}
isInvalid={!!errors.cpu_request}
name="cpu"
/>
</EuiFormRow>
</EuiFlexItem>

<EuiFlexItem>
<EuiFormRow
label={
<FormLabelWithToolTip
label="Image Builder Memory *"
content="To set a higher Mem above platform default for Image Building"
/>
}
isInvalid={!!errors.memory_request}
error={errors.memory_request}
fullWidth
>
<EuiFieldText
placeholder="500Mi"
value={imageBuilderResourceConfig.memory_request}
onChange={(e) => onChange("memory_request")(e.target.value)}
isInvalid={!!errors.memory_request}
name="memory"
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiAccordion>
)}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const maxTicks = 20;
export const ResourcesPanel = ({
environment: initEnvironment,
isGPUEnabled,
child,
resourcesConfig,
onChangeHandler,
errors = {},
Expand Down Expand Up @@ -273,6 +274,12 @@ export const ResourcesPanel = ({
/ Month
</p>
</EuiCallOut>
<EuiSpacer size="s" />
{
child && (
child
)
}
</Panel>
);
};
8 changes: 8 additions & 0 deletions ui/src/pages/version/components/forms/steps/ModelStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DeploymentConfigPanel } from "../components/DeploymentConfigPanel";
import { EnvVariablesPanel } from "../components/EnvVariablesPanel";
import { LoggerPanel } from "../components/LoggerPanel";
import { ResourcesPanel } from "../components/ResourcesPanel";
import { ImageBuilderSection } from "../components/ImageBuilderSection";

export const ModelStep = ({ version, isEnvironmentDisabled = false }) => {
const { data, onChangeHandler } = useContext(FormContext);
Expand Down Expand Up @@ -39,6 +40,13 @@ export const ModelStep = ({ version, isEnvironmentDisabled = false }) => {
onChangeHandler={onChange("resource_request")}
maxAllowedReplica={appConfig.scaling.maxAllowedReplica}
errors={get(errors, "resource_request")}
child={(
<ImageBuilderSection
imageBuilderResourceConfig={data.image_builder_resource_request}
onChangeHandler={onChange("image_builder_resource_request")}
errors={get(errors, "image_builder_resource_request")}
/>
)}
/>
</EuiFlexItem>

Expand Down
13 changes: 13 additions & 0 deletions ui/src/pages/version/components/forms/validation/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { appConfig } from "../../../../../config";

const cpuRequestRegex = /^(\d{1,3}(\.\d{1,3})?)$|^(\d{2,5}m)$/,
memRequestRegex = /^\d+(Ei?|Pi?|Ti?|Gi?|Mi?|Ki?)?$/,
// these are similar to the cpu request, just that it allows empty fields
imageBuilderCpuRequestRegex = /^(\d{1,3}(\.\d{1,3})?)?$|^(\d{2,5}m)$/,
imageBuilderMemRequestRegex = /^(\d+(Ei?|Pi?|Ti?|Gi?|Mi?|Ki?)?)?$/,
envVariableNameRegex = /^[a-z0-9_]*$/i,
dockerImageRegex =
/^([a-z0-9]+(?:[._-][a-z0-9]+)*(?::\d{2,5})?\/)?([a-z0-9]+(?:[._-][a-z0-9]+)*\/)*([a-z0-9]+(?:[._-][a-z0-9]+)*)(?::[a-z0-9]+(?:[._-][a-z0-9]+)*)?$/i;
Expand Down Expand Up @@ -44,6 +47,15 @@ const resourceRequestSchema = yup.object().shape({
),
});

const imagebuilderRequestSchema = yup.object().shape({
cpu_request: yup
.string()
.matches(imageBuilderCpuRequestRegex, 'Valid CPU value is required, e.g "2" or "500m"'),
memory_request: yup
.string()
.matches(imageBuilderMemRequestRegex, "Valid RAM value is required, e.g. 512Mi"),
});

const environmentVariableSchema = yup.object().shape({
name: yup
.string()
Expand All @@ -58,6 +70,7 @@ const environmentVariableSchema = yup.object().shape({
export const versionEndpointSchema = yup.object().shape({
environment_name: yup.string().required("Environment is required"),
resource_request: resourceRequestSchema,
image_builder_resource_request : imagebuilderRequestSchema,
env_vars: yup.array(environmentVariableSchema),
});

Expand Down
7 changes: 6 additions & 1 deletion ui/src/services/version_endpoint/VersionEndpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ export class VersionEndpoint {
min_replica: process.env.REACT_APP_ENVIRONMENT === "production" ? 2 : 0,
max_replica: process.env.REACT_APP_ENVIRONMENT === "production" ? 4 : 2,
cpu_request: "500m",
memory_request: "512Mi"
memory_request: "512Mi",
};

this.image_builder_resource_request = {
cpu_request: "",
memory_request: ""
}

this.env_vars = [];
this.transformer = new Transformer();
this.logger = new Logger();
Expand Down

0 comments on commit 2d1e720

Please sign in to comment.