1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { Card, CardHeader, IconButton, CardContent, Tooltip, Typography, Grid, Link } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { ArvadosTheme } from 'common/custom-theme';
17 } from 'components/icon/icon';
18 import { MPVPanelProps } from 'components/multi-panel-view/multi-panel-view';
19 import { connect } from 'react-redux';
20 import { Process } from 'store/processes/process';
21 import { NodeInstanceType } from 'store/process-panel/process-panel';
22 import { DetailsAttribute } from "components/details-attribute/details-attribute";
23 import { formatFileSize } from "common/formatters";
24 import { MountKind } from 'models/mount-types';
26 interface ProcessResourceCardDataProps {
28 nodeInfo: NodeInstanceType | null;
29 usageReport: string | null;
32 type CssRules = "card" | "header" | "title" | "avatar" | "iconHeader" | "content" | "sectionH3" | "reportButton";
34 const styles: CustomStyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
42 paddingTop: theme.spacing(0.5),
45 paddingTop: theme.spacing(0.5),
49 color: theme.customs.colors.greyL,
53 maxHeight: `calc(100% - ${theme.spacing(7.5)})`,
58 color: theme.customs.colors.greyD,
59 fontSize: "0.8125rem",
60 textTransform: "uppercase",
66 type ProcessResourceCardProps = ProcessResourceCardDataProps & WithStyles<CssRules> & MPVPanelProps;
68 export const ProcessResourceCard = withStyles(styles)(connect()(
69 ({ classes, nodeInfo, usageReport, doHidePanel, doMaximizePanel, doUnMaximizePanel, panelMaximized, panelName, process, }: ProcessResourceCardProps) => {
71 if (process.container?.mounts) {
72 for (const mnt in process.container.mounts) {
73 const mp = process.container.mounts[mnt];
74 if (mp.kind === MountKind.TEMPORARY_DIRECTORY) {
75 diskRequest += mp.capacity;
81 <Card className={classes.card} data-cy="process-resources-card">
83 className={classes.header}
85 content: classes.title,
86 avatar: classes.avatar,
88 avatar={<ResourceIcon className={classes.iconHeader} />}
90 <Typography noWrap variant='h6' color='inherit'>
96 {usageReport && <Link href={usageReport} className={classes.reportButton} target="_blank"><ShowChartIcon /> Resource usage report</Link>}
97 {doUnMaximizePanel && panelMaximized &&
98 <Tooltip title={`Unmaximize ${panelName || 'panel'}`} disableFocusListener>
99 <IconButton onClick={doUnMaximizePanel} size="large"><UnMaximizeIcon /></IconButton>
101 {doMaximizePanel && !panelMaximized &&
102 <Tooltip title={`Maximize ${panelName || 'panel'}`} disableFocusListener>
103 <IconButton onClick={doMaximizePanel} size="large"><MaximizeIcon /></IconButton>
106 <Tooltip title={`Close ${panelName || 'panel'}`} disableFocusListener>
107 <IconButton disabled={panelMaximized} onClick={doHidePanel} size="large"><CloseIcon /></IconButton>
111 <CardContent className={classes.content}>
114 <h3 className={classes.sectionH3}>Requested Resources</h3>
117 <DetailsAttribute label="Cores" value={process.container?.runtimeConstraints.vcpus} />
120 <DetailsAttribute label="RAM*" value={formatFileSize(process.container?.runtimeConstraints.ram)} />
123 <DetailsAttribute label="Disk" value={formatFileSize(diskRequest)} />
126 {process.container?.runtimeConstraints.cuda &&
127 process.container?.runtimeConstraints.cuda.device_count > 0 ?
130 <DetailsAttribute label="CUDA devices" value={process.container?.runtimeConstraints.cuda.device_count} />
133 <DetailsAttribute label="CUDA driver version" value={process.container?.runtimeConstraints.cuda.driver_version} />
136 <DetailsAttribute label="CUDA hardware capability" value={process.container?.runtimeConstraints.cuda.hardware_capability} />
140 {process.container?.runtimeConstraints.keep_cache_ram &&
141 process.container?.runtimeConstraints.keep_cache_ram > 0 ?
143 <DetailsAttribute label="Keep cache (RAM)" value={formatFileSize(process.container?.runtimeConstraints.keep_cache_ram)} />
146 {process.container?.runtimeConstraints.keep_cache_disk &&
147 process.container?.runtimeConstraints.keep_cache_disk > 0 ?
149 <DetailsAttribute label="Keep cache (disk)" value={formatFileSize(process.container?.runtimeConstraints.keep_cache_disk)} />
152 {process.container?.runtimeConstraints.API ? <Grid item xs={12}>
153 <DetailsAttribute label="API access" value={process.container?.runtimeConstraints.API.toString()} />
161 <h3 className={classes.sectionH3}>Assigned Instance Type</h3>
162 {nodeInfo === null ? <Grid item xs={8}>
163 No instance type recorded
168 <DetailsAttribute label="Cores" value={nodeInfo.VCPUs} />
172 <DetailsAttribute label="Provider type" value={nodeInfo.ProviderType} />
176 <DetailsAttribute label="RAM" value={formatFileSize(nodeInfo.RAM)} />
180 <DetailsAttribute label="Price" value={"$" + nodeInfo.Price.toString()} />
184 <DetailsAttribute label="Disk" value={formatFileSize(nodeInfo.IncludedScratch + nodeInfo.AddedScratch)} />
188 <DetailsAttribute label="Preemptible" value={nodeInfo.Preemptible.toString()} />
191 {nodeInfo.CUDA && nodeInfo.CUDA.DeviceCount > 0 &&
194 <DetailsAttribute label="CUDA devices" value={nodeInfo.CUDA.DeviceCount} />
201 <DetailsAttribute label="CUDA driver version" value={nodeInfo.CUDA.DriverVersion} />
208 <DetailsAttribute label="CUDA hardware capability" value={nodeInfo.CUDA.HardwareCapability} />
215 <Typography>* RAM available to the program is limited to Requested RAM, not Instance RAM</Typography>