Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/scripts/update_api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { parseDocument } from "yaml";

const GH_BASE_URL = "https://raw.githubusercontent.com";
const DATA_SERVICES_REPO = "SwissDataScienceCenter/renku-data-services";
const DATA_SERVICES_RELEASE = "main";
const DATA_SERVICES_RELEASE = "leafty/feat-resource-class-platforms";

async function main() {
argv.forEach((arg) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,15 @@ export type EnvironmentWithImageGet = Environment & {
environment_kind: EnvironmentKind;
};
export type Repository = string;
export type BuildPlatform = "linux/amd64" | "linux/arm64";
export type BuildPlatforms = BuildPlatform[];
export type BuilderVariant = string;
export type FrontendVariant = string;
export type RepositoryRevision = string;
export type BuildContextDir = string;
export type BuildParameters = {
repository: Repository;
platforms?: BuildPlatforms;
builder_variant: BuilderVariant;
frontend_variant: FrontendVariant;
repository_revision?: RepositoryRevision;
Expand Down Expand Up @@ -385,6 +388,7 @@ export type RepositoryRevisionPatch = string;
export type BuildContextDirPatch = string;
export type BuildParametersPatch = {
repository?: Repository;
platforms?: BuildPlatforms;
builder_variant?: BuilderVariant;
frontend_variant?: FrontendVariant;
repository_revision?: RepositoryRevisionPatch;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,18 @@
"maxLength": 99,
"example": "My Renku Session :)"
},
"BuildPlatforms": {
"description": "The target runtime platforms of a session environment.",
"type": "array",
"items": {
"$ref": "#/components/schemas/BuildPlatform"
}
},
"BuildPlatform": {
"description": "A runtime platform, e.g. \"linux/amd64\".",
"type": "string",
"enum": ["linux/amd64", "linux/arm64"]
},
"BuilderVariant": {
"description": "Type of virtual environment manager when building custom environments.",
"type": "string",
Expand Down Expand Up @@ -1106,6 +1118,9 @@
"repository": {
"$ref": "#/components/schemas/Repository"
},
"platforms": {
"$ref": "#/components/schemas/BuildPlatforms"
},
"builder_variant": {
"$ref": "#/components/schemas/BuilderVariant"
},
Expand Down Expand Up @@ -1144,6 +1159,9 @@
"repository": {
"$ref": "#/components/schemas/Repository"
},
"platforms": {
"$ref": "#/components/schemas/BuildPlatforms"
},
"builder_variant": {
"$ref": "#/components/schemas/BuilderVariant"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import cx from "classnames";
import { useCallback, useMemo, useState } from "react";
import {
Controller,
type Control,
type FieldValues,
type UseControllerProps,
} from "react-hook-form";
import { Collapse, Label } from "reactstrap";

import ChevronFlippedIcon from "~/components/icons/ChevronFlippedIcon";
import { BUILDER_PLATFORMS } from "../../session.constants";
import type { SessionLauncherForm } from "../../sessionsV2.types";
import BuilderSelectorCommon from "./BuilderSelectorCommon";

interface BuilderAdvancedSettingsProps {
control: Control<SessionLauncherForm>;
}

export default function BuilderAdvancedSettings({
control,
}: BuilderAdvancedSettingsProps) {
const [isOpen, setIsOpen] = useState(false);
const toggleIsOpen = useCallback(
() => setIsOpen((isAdvancedSettingOpen) => !isAdvancedSettingOpen),
[]
);
return (
<div className={cx("d-flex", "flex-column", "gap-1")}>
<button
className={cx(
"d-flex",
"align-items-center",
"w-100",
"bg-transparent",
"border-0",
"p-0",
"h4"
)}
type="button"
onClick={toggleIsOpen}
>
Advanced settings
<ChevronFlippedIcon className="ms-1" flipped={isOpen} />
</button>
<Collapse isOpen={isOpen}>
<div className={cx("d-flex", "flex-column", "gap-3")}>
<BuilderPlatformSelector name="platform" control={control} />
</div>
</Collapse>
</div>
);
}

interface BuilderPlatformSelectorProps<T extends FieldValues>
extends UseControllerProps<T> {}

function BuilderPlatformSelector<T extends FieldValues>({
...controllerProps
}: BuilderPlatformSelectorProps<T>) {
const defaultValue = useMemo(
() =>
controllerProps.defaultValue
? controllerProps.defaultValue
: BUILDER_PLATFORMS[0],
[controllerProps.defaultValue]
);

return (
<div>
<Label for="builder-environment-platform-select-input">Platform</Label>
<Controller
{...controllerProps}
render={({
field: { onBlur, onChange, value, disabled },
fieldState: { error },
}) => (
<>
<div
className={cx(error && "is-invalid")}
data-cy="environment-platform-select"
>
<BuilderSelectorCommon
defaultValue={defaultValue}
disabled={disabled}
id="builder-environment-platform-select"
inputId="builder-environment-platform-select-input"
name={controllerProps.name}
onBlur={onBlur}
onChange={onChange}
options={BUILDER_PLATFORMS}
value={value ?? ""}
/>
</div>
<div className="invalid-feedback">
{error?.message ? (
<>{error.message}</>
) : (
<>Please select a valid platform.</>
)}
</div>
</>
)}
rules={
controllerProps.rules ?? {
required: "Please select a platform.",
}
}
/>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { DEFAULT_APP_PARAMS } from "../../../../utils/context/appParams.constant
import { useProject } from "../../../ProjectPageV2/ProjectPageContainer/ProjectPageContainer";
import { useGetRepositoriesProbesQuery } from "../../../repositories/repositories.api";
import type { SessionLauncherForm } from "../../sessionsV2.types";
import BuilderAdvancedSettings from "./BuilderAdvancedSettings";
import BuilderFrontendSelector from "./BuilderFrontendSelector";
import BuilderTypeSelector from "./BuilderTypeSelector";
import CodeRepositoryAdvancedSettings from "./CodeRepositoryAdvancedSettings";
Expand Down Expand Up @@ -104,6 +105,7 @@ export default function BuilderEnvironmentFields({
</div>
<BuilderTypeSelector name="builder_variant" control={control} />
<BuilderFrontendSelector name="frontend_variant" control={control} />
<BuilderAdvancedSettings control={control} />
</div>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default function NewSessionLauncherModal({
default_url: DEFAULT_URL,
port: DEFAULT_PORT,
repository: "",
platform: "",
},
});
const {
Expand Down
15 changes: 15 additions & 0 deletions client/src/features/sessionsV2/session.constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,21 @@ export const BUILDER_FRONTENDS = [
},
] as readonly BuilderSelectorOption[];

export const BUILDER_PLATFORMS = [
{
value: "linux/amd64" as const,
label: "linux/amd64",
description:
"The default runtime platform. Select this option unless you know your session will run on a different platform.",
},
{
value: "linux/arm64" as const,
label: "linux/arm64",
description:
"Select this option if your session will run on ARM64 compute resources.",
},
] as readonly BuilderSelectorOption<"linux/amd64" | "linux/arm64">[];

export const IMAGE_BUILD_DOCS =
"https://renku.notion.site/How-to-create-a-custom-environment-from-a-code-repository-1960df2efafc801b88f6da59a0aa8234";

Expand Down
19 changes: 18 additions & 1 deletion client/src/features/sessionsV2/session.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ import type {
SessionLauncherEnvironmentPatchParams,
} from "./api/sessionLaunchersV2.api";
import {
BUILDER_PLATFORMS,
DEFAULT_URL,
ENV_VARIABLES_RESERVED_PREFIX,
} from "./session.constants";
import { SessionLauncherForm } from "./sessionsV2.types";
import type { SessionLauncherForm } from "./sessionsV2.types";

export function getSessionFavicon(
sessionState?: SessionStatusState,
Expand Down Expand Up @@ -103,6 +104,7 @@ export function getFormattedEnvironmentValues(data: SessionLauncherForm): {
gid,
mount_directory,
name,
platform: platform_,
port,
repository_revision: repository_revision_,
repository,
Expand All @@ -118,13 +120,18 @@ export function getFormattedEnvironmentValues(data: SessionLauncherForm): {
if (environmentSelect === "custom + build") {
const context_dir = context_dir_?.trim();
const repository_revision = repository_revision_?.trim();
const platform =
BUILDER_PLATFORMS.map(({ value }) => value).find(
(value) => value === platform_
) ?? BUILDER_PLATFORMS[0].value;
return {
success: true,
data: {
environment_image_source: "build",
builder_variant,
frontend_variant,
repository,
platforms: [platform],
...(context_dir ? { context_dir } : {}),
...(repository_revision ? { repository_revision } : {}),
},
Expand Down Expand Up @@ -203,9 +210,14 @@ export function getFormattedEnvironmentValuesForEdit(
builder_variant,
context_dir,
frontend_variant,
platform: platform_,
repository_revision,
repository,
} = data;
const platform =
BUILDER_PLATFORMS.map(({ value }) => value).find(
(value) => value === platform_
) ?? BUILDER_PLATFORMS[0].value;

return {
success: true,
Expand All @@ -218,6 +230,7 @@ export function getFormattedEnvironmentValuesForEdit(
repository,
repository_revision: repository_revision ?? "",
context_dir: context_dir ?? "",
platforms: [platform],
},
},
};
Expand Down Expand Up @@ -277,6 +290,10 @@ export function getLauncherDefaultValues(
launcher.environment.environment_image_source === "build"
? launcher.environment.build_parameters.context_dir ?? ""
: "",
platform:
launcher.environment.environment_image_source === "build"
? launcher.environment.build_parameters.platforms?.at(0) ?? ""
: "",
};
}

Expand Down
11 changes: 7 additions & 4 deletions client/src/features/sessionsV2/sessionsV2.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import type { ReactNode } from "react";

import type { CloudStorageDetailsOptions } from "../project/components/cloudStorage/projectCloudStorage.types";
import type { ResourceClassWithId } from "./api/computeResources.generated-api";
import type { ResourceClassWithId } from "./api/computeResources.api";
import type {
BuildParametersPost,
DefaultUrl,
Expand Down Expand Up @@ -103,7 +103,7 @@ export interface SessionLauncherForm
// For "global" environments
environmentId: EnvironmentId;

// For "custom" + "image" environments
// For "custom + image" environments
default_url: DefaultUrl;
uid: EnvironmentUid;
gid: EnvironmentGid;
Expand All @@ -112,6 +112,9 @@ export interface SessionLauncherForm
args: string;
command: string;
strip_path_prefix: boolean;

// For "custom + build" environments
platform: string;
}

export interface SessionResources {
Expand Down Expand Up @@ -182,9 +185,9 @@ export interface DockerImage {
error?: unknown;
}

export interface BuilderSelectorOption {
export interface BuilderSelectorOption<T extends string = string> {
label: string;
value: string;
value: T;
description?: ReactNode;
}

Expand Down
Loading