[arvados] updated: 2.7.0-6002-gff660b5e08

git repository hosting git at public.arvados.org
Wed Feb 14 02:34:37 UTC 2024


Summary of changes:
 sdk/cwl/arvados_cwl/arvcontainer.py                |  4 +-
 sdk/cwl/arvados_version.py                         |  1 +
 .../store/process-panel/process-panel-actions.ts   |  7 +-
 .../store/process-panel/process-panel-reducer.ts   |  4 ++
 .../src/store/process-panel/process-panel.ts       |  6 ++
 .../src/views/process-panel/process-panel-root.tsx |  4 ++
 .../src/views/process-panel/process-panel.tsx      |  9 ++-
 .../views/process-panel/process-resource-card.tsx  |  6 +-
 .../crunchstat_summary/summarizer.py               |  2 +-
 .../crunchstat_summary/webchart.py                 | 75 ++++++++++++++++------
 10 files changed, 93 insertions(+), 25 deletions(-)

       via  ff660b5e081301201832ac7b33ea12cceb84bc3d (commit)
       via  c66cf8a682bd326a38c069045bfc116c61603bc8 (commit)
       via  63be99931dcf5301ca75e9bc8eb049c86174eb0c (commit)
      from  b654b9c6bc67bc6de5e9fe08484acbfe7e1a7fad (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit ff660b5e081301201832ac7b33ea12cceb84bc3d
Author: Peter Amstutz <peter.amstutz at curii.com>
Date:   Tue Feb 13 21:34:17 2024 -0500

    19744: Made the resource usage report button obvious
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz at curii.com>

diff --git a/services/workbench2/src/views/process-panel/process-panel-root.tsx b/services/workbench2/src/views/process-panel/process-panel-root.tsx
index ce81bd74c2..2a9b3882e8 100644
--- a/services/workbench2/src/views/process-panel/process-panel-root.tsx
+++ b/services/workbench2/src/views/process-panel/process-panel-root.tsx
@@ -46,7 +46,7 @@ export interface ProcessPanelRootDataProps {
     outputDefinitions: CommandOutputParameter[];
     outputParams: ProcessIOParameter[] | null;
     nodeInfo: NodeInstanceType | null;
-    usageReport: CollectionFile | null;
+    usageReport: string | null;
 }
 
 export interface ProcessPanelRootActionProps {
diff --git a/services/workbench2/src/views/process-panel/process-panel.tsx b/services/workbench2/src/views/process-panel/process-panel.tsx
index 5c2dd237aa..f305290cc0 100644
--- a/services/workbench2/src/views/process-panel/process-panel.tsx
+++ b/services/workbench2/src/views/process-panel/process-panel.tsx
@@ -21,12 +21,14 @@ import {
 import { cancelRunningWorkflow, resumeOnHoldWorkflow, startWorkflow } from "store/processes/processes-actions";
 import { navigateToLogCollection, pollProcessLogs, setProcessLogsPanelFilter } from "store/process-logs-panel/process-logs-panel-actions";
 import { snackbarActions, SnackbarKind } from "store/snackbar/snackbar-actions";
+import { getInlineFileUrl } from "views-components/context-menu/actions/helpers";
 
 const mapStateToProps = ({ router, auth, resources, processPanel, processLogsPanel }: RootState): ProcessPanelRootDataProps => {
     const uuid = getProcessPanelCurrentUuid(router) || "";
     const subprocesses = getSubprocesses(uuid)(resources);
+    const process = getProcess(uuid)(resources);
     return {
-        process: getProcess(uuid)(resources),
+        process,
         subprocesses: subprocesses.filter(subprocess => processPanel.filters[getProcessStatus(subprocess)]),
         filters: getFilters(processPanel, subprocesses),
         processLogsPanel: processLogsPanel,
@@ -37,7 +39,11 @@ const mapStateToProps = ({ router, auth, resources, processPanel, processLogsPan
         outputDefinitions: processPanel.outputDefinitions,
         outputParams: processPanel.outputParams,
         nodeInfo: processPanel.nodeInfo,
-        usageReport: processPanel.usageReport,
+        usageReport: (process || null) && processPanel.usageReport && getInlineFileUrl(
+            `${auth.config.keepWebServiceUrl}${processPanel.usageReport.url}?api_token=${auth.apiToken}`,
+            auth.config.keepWebServiceUrl,
+            auth.config.keepWebInlineServiceUrl
+        ),
     };
 };
 
diff --git a/services/workbench2/src/views/process-panel/process-resource-card.tsx b/services/workbench2/src/views/process-panel/process-resource-card.tsx
index 179335175e..1832fe4744 100644
--- a/services/workbench2/src/views/process-panel/process-resource-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-resource-card.tsx
@@ -15,6 +15,7 @@ import {
     Typography,
     Grid,
     Link,
+    Button
 } from '@material-ui/core';
 import { ArvadosTheme } from 'common/custom-theme';
 import {
@@ -30,12 +31,11 @@ import { NodeInstanceType } from 'store/process-panel/process-panel';
 import { DetailsAttribute } from "components/details-attribute/details-attribute";
 import { formatFileSize } from "common/formatters";
 import { MountKind } from 'models/mount-types';
-import { CollectionFile } from 'models/collection-file';
 
 interface ProcessResourceCardDataProps {
     process: Process;
     nodeInfo: NodeInstanceType | null;
-    usageReport: CollectionFile | null;
+    usageReport: string | null;
 }
 
 type CssRules = "card" | "header" | "title" | "avatar" | "iconHeader" | "content" | "sectionH3";
@@ -99,6 +99,7 @@ export const ProcessResourceCard = withStyles(styles)(connect()(
                 }
                 action={
                     <div>
+                        {usageReport && <Button href={usageReport} variant="contained" color="primary">Resource usage report</Button>}
                         {doUnMaximizePanel && panelMaximized &&
                             <Tooltip title={`Unmaximize ${panelName || 'panel'}`} disableFocusListener>
                                 <IconButton onClick={doUnMaximizePanel}><UnMaximizeIcon /></IconButton>
@@ -114,7 +115,6 @@ export const ProcessResourceCard = withStyles(styles)(connect()(
                     </div>
                 } />
             <CardContent className={classes.content}>
-                {usageReport && <Link href={usageReport.url}>Resource usage report</Link>}
                 <Grid container>
                     <Grid item xs={4}>
                         <h3 className={classes.sectionH3}>Requested Resources</h3>

commit c66cf8a682bd326a38c069045bfc116c61603bc8
Author: Peter Amstutz <peter.amstutz at curii.com>
Date:   Tue Feb 13 19:54:56 2024 -0500

    19744: Calling it the usage report
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz at curii.com>

diff --git a/sdk/cwl/arvados_cwl/arvcontainer.py b/sdk/cwl/arvados_cwl/arvcontainer.py
index 534f940b03..b7ef13070a 100644
--- a/sdk/cwl/arvados_cwl/arvcontainer.py
+++ b/sdk/cwl/arvados_cwl/arvcontainer.py
@@ -536,9 +536,7 @@ class ArvadosContainer(JobBase):
             if logc is not None:
                 summerizer = crunchstat_summary.summarizer.NewSummarizer(self.uuid)
                 summerizer.run()
-                with logc.open("metrics_report.txt", "wt") as mr:
-                    mr.write(summerizer.text_report())
-                with logc.open("metrics_report.html", "wt") as mr:
+                with logc.open("usage_report.html", "wt") as mr:
                     mr.write(summerizer.html_report())
                 logc.save()
 
diff --git a/sdk/cwl/arvados_version.py b/sdk/cwl/arvados_version.py
index c3936617f0..a78dbfcf2b 100644
--- a/sdk/cwl/arvados_version.py
+++ b/sdk/cwl/arvados_version.py
@@ -12,6 +12,7 @@ SETUP_DIR = os.path.dirname(os.path.abspath(__file__))
 VERSION_PATHS = {
         SETUP_DIR,
         os.path.abspath(os.path.join(SETUP_DIR, "../python")),
+        os.path.abspath(os.path.join(SETUP_DIR, "../../tools/crunchstat-summary")),
         os.path.abspath(os.path.join(SETUP_DIR, "../../build/version-at-commit.sh"))
         }
 
diff --git a/services/workbench2/src/store/process-panel/process-panel-actions.ts b/services/workbench2/src/store/process-panel/process-panel-actions.ts
index cbf89983c9..82c267c7a0 100644
--- a/services/workbench2/src/store/process-panel/process-panel-actions.ts
+++ b/services/workbench2/src/store/process-panel/process-panel-actions.ts
@@ -18,7 +18,7 @@ import { ContainerRequestResource } from "models/container-request";
 import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter";
 import { CommandInputParameter, getIOParamId, WorkflowInputsData } from "models/workflow";
 import { getIOParamDisplayValue, ProcessIOParameter } from "views/process-panel/process-io-card";
-import { OutputDetails, NodeInstanceType, NodeInfo } from "./process-panel";
+import { OutputDetails, NodeInstanceType, NodeInfo, UsageReport } from "./process-panel";
 import { AuthState } from "store/auth/auth-reducer";
 import { ContextMenuResource } from "store/context-menu/context-menu-actions";
 import { OutputDataUpdate } from "./process-panel-reducer";
@@ -34,6 +34,7 @@ export const processPanelActions = unionize({
     SET_OUTPUT_DEFINITIONS: ofType<CommandOutputParameter[]>(),
     SET_OUTPUT_PARAMS: ofType<ProcessIOParameter[] | null>(),
     SET_NODE_INFO: ofType<NodeInfo>(),
+    SET_USAGE_REPORT: ofType<UsageReport>(),
 });
 
 export type ProcessPanelAction = UnionOf<typeof processPanelActions>;
@@ -145,8 +146,12 @@ export const loadNodeJson =
             } else {
                 dispatch<ProcessPanelAction>(processPanelActions.SET_NODE_INFO(noLog));
             }
+
+            const usageReportFile = files.find(file => file.name === "usage_report.html") as CollectionFile | null;
+            dispatch<ProcessPanelAction>(processPanelActions.SET_USAGE_REPORT({ usageReport: usageReportFile }));
         } catch {
             dispatch<ProcessPanelAction>(processPanelActions.SET_NODE_INFO(noLog));
+            dispatch<ProcessPanelAction>(processPanelActions.SET_USAGE_REPORT({ usageReport: null }));
         }
     };
 
diff --git a/services/workbench2/src/store/process-panel/process-panel-reducer.ts b/services/workbench2/src/store/process-panel/process-panel-reducer.ts
index 5c1b916c3a..ab95b6ac32 100644
--- a/services/workbench2/src/store/process-panel/process-panel-reducer.ts
+++ b/services/workbench2/src/store/process-panel/process-panel-reducer.ts
@@ -14,6 +14,7 @@ const initialState: ProcessPanel = {
     nodeInfo: null,
     outputDefinitions: [],
     outputParams: null,
+    usageReport: null,
 };
 
 export type OutputDataUpdate = {
@@ -75,5 +76,8 @@ export const processPanelReducer = (state = initialState, action: ProcessPanelAc
         SET_OUTPUT_PARAMS: outputParams => {
             return { ...state, outputParams };
         },
+        SET_USAGE_REPORT: ({ usageReport }) => {
+            return { ...state, usageReport };
+        },
         default: () => state,
     });
diff --git a/services/workbench2/src/store/process-panel/process-panel.ts b/services/workbench2/src/store/process-panel/process-panel.ts
index 35d776edc7..12a46a272c 100644
--- a/services/workbench2/src/store/process-panel/process-panel.ts
+++ b/services/workbench2/src/store/process-panel/process-panel.ts
@@ -7,6 +7,7 @@ import { RouterState } from "react-router-redux";
 import { matchProcessRoute } from "routes/routes";
 import { ProcessIOParameter } from "views/process-panel/process-io-card";
 import { CommandOutputParameter } from 'cwlts/mappings/v1.0/CommandOutputParameter';
+import { CollectionFile } from 'models/collection-file';
 
 export type OutputDetails = {
     raw?: any;
@@ -36,6 +37,10 @@ export interface NodeInfo {
     nodeInfo: NodeInstanceType | null;
 };
 
+export interface UsageReport {
+    usageReport: CollectionFile | null;
+};
+
 export interface ProcessPanel {
     containerRequestUuid: string;
     filters: { [status: string]: boolean };
@@ -45,6 +50,7 @@ export interface ProcessPanel {
     outputDefinitions: CommandOutputParameter[];
     outputParams: ProcessIOParameter[] | null;
     nodeInfo: NodeInstanceType | null;
+    usageReport: CollectionFile | null;
 }
 
 export const getProcessPanelCurrentUuid = (router: RouterState) => {
diff --git a/services/workbench2/src/views/process-panel/process-panel-root.tsx b/services/workbench2/src/views/process-panel/process-panel-root.tsx
index 774e572cc9..ce81bd74c2 100644
--- a/services/workbench2/src/views/process-panel/process-panel-root.tsx
+++ b/services/workbench2/src/views/process-panel/process-panel-root.tsx
@@ -24,6 +24,7 @@ import { ProcessCmdCard } from "./process-cmd-card";
 import { ContainerRequestResource } from "models/container-request";
 import { OutputDetails, NodeInstanceType } from "store/process-panel/process-panel";
 import { NotFoundView } from 'views/not-found-panel/not-found-panel';
+import { CollectionFile } from 'models/collection-file';
 
 type CssRules = "root";
 
@@ -45,6 +46,7 @@ export interface ProcessPanelRootDataProps {
     outputDefinitions: CommandOutputParameter[];
     outputParams: ProcessIOParameter[] | null;
     nodeInfo: NodeInstanceType | null;
+    usageReport: CollectionFile | null;
 }
 
 export interface ProcessPanelRootActionProps {
@@ -87,6 +89,7 @@ export const ProcessPanelRoot = withStyles(styles)(
         outputDefinitions,
         outputParams,
         nodeInfo,
+        usageReport,
         loadInputs,
         loadOutputs,
         loadNodeJson,
@@ -208,6 +211,7 @@ export const ProcessPanelRoot = withStyles(styles)(
                     <ProcessResourceCard
                         process={process}
                         nodeInfo={nodeInfo}
+                        usageReport={usageReport}
                     />
                 </MPVPanelContent>
             </MPVContainer>
diff --git a/services/workbench2/src/views/process-panel/process-panel.tsx b/services/workbench2/src/views/process-panel/process-panel.tsx
index 7e175c4799..5c2dd237aa 100644
--- a/services/workbench2/src/views/process-panel/process-panel.tsx
+++ b/services/workbench2/src/views/process-panel/process-panel.tsx
@@ -37,6 +37,7 @@ const mapStateToProps = ({ router, auth, resources, processPanel, processLogsPan
         outputDefinitions: processPanel.outputDefinitions,
         outputParams: processPanel.outputParams,
         nodeInfo: processPanel.nodeInfo,
+        usageReport: processPanel.usageReport,
     };
 };
 
diff --git a/services/workbench2/src/views/process-panel/process-resource-card.tsx b/services/workbench2/src/views/process-panel/process-resource-card.tsx
index 4e849173fb..179335175e 100644
--- a/services/workbench2/src/views/process-panel/process-resource-card.tsx
+++ b/services/workbench2/src/views/process-panel/process-resource-card.tsx
@@ -14,6 +14,7 @@ import {
     Tooltip,
     Typography,
     Grid,
+    Link,
 } from '@material-ui/core';
 import { ArvadosTheme } from 'common/custom-theme';
 import {
@@ -29,10 +30,12 @@ import { NodeInstanceType } from 'store/process-panel/process-panel';
 import { DetailsAttribute } from "components/details-attribute/details-attribute";
 import { formatFileSize } from "common/formatters";
 import { MountKind } from 'models/mount-types';
+import { CollectionFile } from 'models/collection-file';
 
 interface ProcessResourceCardDataProps {
     process: Process;
     nodeInfo: NodeInstanceType | null;
+    usageReport: CollectionFile | null;
 }
 
 type CssRules = "card" | "header" | "title" | "avatar" | "iconHeader" | "content" | "sectionH3";
@@ -70,7 +73,7 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 type ProcessResourceCardProps = ProcessResourceCardDataProps & WithStyles<CssRules> & MPVPanelProps;
 
 export const ProcessResourceCard = withStyles(styles)(connect()(
-    ({ classes, nodeInfo, doHidePanel, doMaximizePanel, doUnMaximizePanel, panelMaximized, panelName, process, }: ProcessResourceCardProps) => {
+    ({ classes, nodeInfo, usageReport, doHidePanel, doMaximizePanel, doUnMaximizePanel, panelMaximized, panelName, process, }: ProcessResourceCardProps) => {
         let diskRequest = 0;
         if (process.container?.mounts) {
             for (const mnt in process.container.mounts) {
@@ -111,6 +114,7 @@ export const ProcessResourceCard = withStyles(styles)(connect()(
                     </div>
                 } />
             <CardContent className={classes.content}>
+                {usageReport && <Link href={usageReport.url}>Resource usage report</Link>}
                 <Grid container>
                     <Grid item xs={4}>
                         <h3 className={classes.sectionH3}>Requested Resources</h3>

commit 63be99931dcf5301ca75e9bc8eb049c86174eb0c
Author: Peter Amstutz <peter.amstutz at curii.com>
Date:   Tue Feb 13 18:58:43 2024 -0500

    19744: Apply styling to roughly match workbench
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz at curii.com>

diff --git a/tools/crunchstat-summary/crunchstat_summary/summarizer.py b/tools/crunchstat-summary/crunchstat_summary/summarizer.py
index 2bf334b1f6..75d49095d9 100644
--- a/tools/crunchstat-summary/crunchstat_summary/summarizer.py
+++ b/tools/crunchstat-summary/crunchstat_summary/summarizer.py
@@ -317,7 +317,7 @@ class Summarizer(object):
              self.elapsed_time(),
              None,
              ''),
-                ('Max CPU time spent{}'.format(by_single_task),
+                ('CPU time spent{}'.format(by_single_task),
                  self.stats_max['cpu']['user+sys'],
                  None,
                  's'),
diff --git a/tools/crunchstat-summary/crunchstat_summary/webchart.py b/tools/crunchstat-summary/crunchstat_summary/webchart.py
index 4c596902ba..9aedaa0445 100644
--- a/tools/crunchstat-summary/crunchstat_summary/webchart.py
+++ b/tools/crunchstat-summary/crunchstat_summary/webchart.py
@@ -20,6 +20,40 @@ class WebChart(object):
     JSLIB = None
     JSASSET = None
 
+    STYLE = '''
+        body {
+          background: #fafafa;
+          font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+          font-size: 0.875rem;
+          color: rgba(0, 0, 0, 0.87);
+          font-weight: 400;
+        }
+        .card {
+          background: #ffffff;
+          box-shadow: 0px 1px 5px 0px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 3px 1px -2px rgba(0,0,0,0.12);
+          border-radius: 4px;
+          margin: 20px;
+        }
+        .content {
+          padding: 2px 16px 8px 16px;
+        }
+        table {
+          border-spacing: 0px;
+        }
+        tr {
+          height: 36px;
+          text-align: left;
+        }
+        th {
+          padding-right: 4em;
+          border-top: 1px solid rgba(224, 224, 224, 1);
+        }
+        td {
+          padding-right: 2em;
+          border-top: 1px solid rgba(224, 224, 224, 1);
+        }
+    '''
+
     def __init__(self, label, summarizers):
         self.label = label
         self.summarizers = summarizers
@@ -30,35 +64,40 @@ class WebChart(object):
         <script type="text/javascript" src="{}"></script>
         <script type="text/javascript">{}</script>
         <style>
-        table {{
-          width: 90%
-        }}
-        td {{
-          width: 20%
-        }}
-        #chart {{
-          margin-top: 2em;
-        }}
-        #bottomhtml {{
-          margin-top: 4em;
-        }}
+        {}
         </style>
         {}
         </head>
         <body>
-        <h1>{}</h1>
-        <div id="tophtml">
-        {}
+        <div class="card">
+          <div class="content">
+            <h1>{}</h1>
+          </div>
         </div>
-        <div id="chart"></div>
-        <div id="bottomhtml">
-        {}
+        <div class="card">
+          <div class="content" id="tophtml">
+          <h2>Summary</h2>
+          {}
+          </div>
+        </div>
+        <div class="card">
+          <div class="content">
+            <h2>Graph</h2>
+            <div id="chart"></div>
+          </div>
+        </div>
+        <div class="card">
+          <div class="content" id="bottomhtml">
+          <h2>Metrics</h2>
+          {}
+          </div>
         </div>
         </body>
         </html>
         '''.format(escape(self.label),
                    self.JSLIB,
                    self.js(),
+                   self.STYLE,
                    self.headHTML(),
                    escape(self.label),
                    beforechart,

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list