Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 1 addition & 3 deletions src/components/admin/CELExprBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Stack, TextField, IconButton, Chip, Typography } from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import { useState } from "react";

// Simple CEL validation function (stub, replace with real parser)
// Simple CEL validation function (stub, TODO: replace with real parser)
const validateCel = (expr: string): boolean => {
try {
if (!expr) return true; // empty allowed
Expand Down Expand Up @@ -52,7 +52,6 @@ export default function CelExprBuilder({
<Stack spacing={1}>
<Typography variant="subtitle2">{label}</Typography>

{/* Existing expressions as Chips */}
<Stack direction="row" spacing={1} flexWrap="wrap">
{value.map((expr, idx) => {
const valid = validateCel(expr);
Expand All @@ -67,7 +66,6 @@ export default function CelExprBuilder({
})}
</Stack>

{/* Input field for new expression */}
<Stack direction="row" spacing={1}>
<TextField
fullWidth
Expand Down
29 changes: 11 additions & 18 deletions src/components/admin/GPUClaimEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
GenericDeviceConfiguration,
RequestedGpuCreate,
} from "../../temporaryTypesRemoveMe";
import CelExprBuilder from "./CELExprBuilder";

interface Props {
value: RequestedGpuCreate[];
Expand Down Expand Up @@ -103,24 +104,16 @@ export default function GpuClaimEditor({ value, onChange }: Props) {
required
/>

{/*gpu.selectors?.find(((s as any)) => "cel" in s) && (
<CelExprBuilder
value={[
(gpu.selectors!.find(((s as any)) => "cel" in s) as any).cel
.expression,
]} // wrap as array
onChange={(newExpressions) => {
const newSelectors = gpu.selectors!.map((s) =>
"cel" in s
? { cel: { expression: newExpressions[0] } } // update CEL
: s
);
updateRequested(idx, { selectors: newSelectors });
}}
label="Selectors (CEL expression)"
placeholder="gpu.memory > 4 && gpu.computeCapability >= 7.0"
/>
)*/}
<CelExprBuilder
value={gpu.selectors || []}
onChange={(exprs) => {
updateRequested(idx, {
selectors: exprs,
});
}}
label="Selectors (CEL expression)"
placeholder="memory <= 16 && cudaComputeCapability >= 7.0"
/>

<Stack spacing={2}>
<Typography>{"Driver configuration"}</Typography>
Expand Down
2 changes: 1 addition & 1 deletion src/components/admin/GPUClaimModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Role =
| "admin"
| string;

function getChipColor(role: Role) {
export function getChipColor(role: Role) {
const metalStyles: Record<string, any> = {
bronze: {
background:
Expand Down
6 changes: 5 additions & 1 deletion src/components/create/GpuSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ export default function GPUSelector({ gpus, setGpus, zone }: GPUSelectorProps) {
}
>
<span>
<Iconify icon="mdi:help-circle-outline" color="primary.main" />
<Iconify
icon="mdi:help-circle-outline"
color="primary.main"
sx={{ fontSize: 20 }}
/>
</span>
</Tooltip>
}
Expand Down
5 changes: 4 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
"onboarding-resources-3": "If you need more resources, please contact us on Discord!",
"onboarding-deployments-1": "Deployments are the most common resource type on kthcloud. They are perfect for running experiments, or hosting websites.",
"onboarding-deployments-2": "All you need is a Docker image or a repo with a Dockerfile, and a little bit of configuration. kthcloud will take care of the rest.",
"onboarding-deployments-3": "You can add GPU compute to your deployment to use for machine learning.",
"onboarding-vms-1": "Virtual machines are the most flexible resource type on kthcloud. You can install any programs you want and have full control over the machine.",
"onboarding-vms-2": "Virtual machines are perfect for running machine learning models, databases and other more complex applications.",
"onboarding-vms-3": "You can also request a GPU for your virtual machine. Please note that GPU resources are limited, for extended use you may want to provide your own GPU.",
Expand Down Expand Up @@ -582,6 +583,8 @@
"delete-all-expired": "Delete all expired",
"custom-deployment": "Custom",
"custom-deployment-description": "Build and use your own image, use CI/CD through Github actions / Gitlab workflows or build and push your own image. Secrets will be provided after the deployment is created",
"deployment-spec-selector": "Select specs"
"deployment-spec-selector": "Select specs",
"deployment-ssh-info": "SSH into your deployments using a private key linked to a public key in your profile",
"deployment-ssh-view-keys": "View your ssh keys in your profile"
}
}
4 changes: 3 additions & 1 deletion src/locales/se.json
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@
"delete-all-expired": "Ta bort alla utgågna",
"custom-deployment": "Egen",
"custom-deployment-description": "Bygg och använd din egna image, använd CI/CD via Github actions / Gitlab workflows eller bygg och pusha din egna image. Nycklar går att se när din deployment är skapad",
"deployment-spec-selector": "Välj specifikationer"
"deployment-spec-selector": "Välj specifikationer",
"deployment-ssh-info": "SSH:a till dina deployments med en privat nyckel kopplad till en offentlig nyckel i din profil",
"deployment-ssh-view-keys": "Se dina SSH nycklar i din profil"
}
}
18 changes: 18 additions & 0 deletions src/pages/admin/AdminV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Label from "../../components/Label";
import TimeAgo from "../../components/admin/TimeAgo";
import CluseterOverviewTab from "../../components/admin/ClusterOverviewTab";
import { deleteGpuClaim } from "../../api/deploy/gpuClaims";
import { getChipColor } from "../../components/admin/GPUClaimModal";

export default function AdminV2() {
const { tab: initialTab } = useParams();
Expand Down Expand Up @@ -333,6 +334,23 @@ export default function AdminV2() {
{ id: "id", label: "ID" },
{ id: "name", label: "Name" },
{ id: "zone", label: "Zone" },
{
id: "allowedRoles",
label: "Allowed Roles",
renderFunc: (allowedRoles: string[] | undefined) => {
return (
<Stack gap={0.5}>
{allowedRoles ? (
allowedRoles.map((role) => (
<Chip label={role} size="small" {...getChipColor(role)} />
))
) : (
<Chip label={"all"} size="small" />
)}
</Stack>
);
},
},
{
id: "*",
label: "Requested",
Expand Down
3 changes: 2 additions & 1 deletion src/pages/edit/Specs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ export const Specs = ({ resource }: { resource: Resource }) => {
<span>
<Iconify
icon="mdi:help-circle-outline"
color={theme.palette.text.secondary}
color="primary.main"
sx={{ fontSize: 20 }}
/>
</span>
</Tooltip>
Expand Down
34 changes: 34 additions & 0 deletions src/pages/edit/deployments/SSHString.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import {
Card,
CardContent,
CardHeader,
IconButton,
Skeleton,
Stack,
Tooltip,
Typography,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import CopyButton from "../../../components/CopyButton";
import { Deployment } from "../../../types";
import Iconify from "../../../components/Iconify";
import { useNavigate } from "react-router-dom";

const SSHString = ({ deployment }: { deployment: Deployment }) => {
const navigate = useNavigate();
const { t } = useTranslation();
const sshBase =
import.meta.env.VITE_DEPLOYMENT_SSH_BASE ?? window.location.hostname;
Expand All @@ -22,6 +27,35 @@ const SSHString = ({ deployment }: { deployment: Deployment }) => {
<CardHeader
title={t("ssh-string")}
subheader={t("ssh-string-subheader-deployment")}
action={
<Stack direction="row" alignItems="center">
<Tooltip title={t("deployment-ssh-view-keys")}>
<IconButton
color="primary"
onClick={() => navigate("/profile")}
sx={{ fontSize: 20 }}
>
<Iconify icon="mdi:key-outline" />
</IconButton>
</Tooltip>
<Tooltip
enterTouchDelay={10}
title={
<>
<Typography variant="caption">
{t("deployment-ssh-info")}
</Typography>
</>
}
>
<Iconify
icon="mdi:help-circle-outline"
color="primary.main"
sx={{ fontSize: 20 }}
/>
</Tooltip>
</Stack>
}
/>
<CardContent>
{!ssh ? (
Expand Down
4 changes: 4 additions & 0 deletions src/pages/onboarding/Onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ export const Onboarding = () => {
<Typography variant="body1" gutterBottom mb={3}>
{t("onboarding-deployments-2")}
</Typography>

<Typography variant="body1" gutterBottom mb={3}>
{t("onboarding-deployments-3")}
</Typography>
</OnboardingCard>
</div>
</Fade>
Expand Down
Loading