Skip to content

Commit

Permalink
fix(ui): Change pod names to new format. Fixes #6865 (#6925)
Browse files Browse the repository at this point in the history
  • Loading branch information
JPZ13 authored and sarabala1979 committed Oct 19, 2021
1 parent 5df91b2 commit 7cdbee0
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {ResourceEditor} from '../../../shared/components/resource-editor/resourc
import {services} from '../../../shared/services';
import {WorkflowArtifacts} from '../../../workflows/components/workflow-artifacts';

import {Utils} from '../../../shared/utils';
import {WorkflowResourcePanel} from '../../../workflows/components/workflow-details/workflow-resource-panel';
import {WorkflowLogsViewer} from '../../../workflows/components/workflow-logs-viewer/workflow-logs-viewer';
import {WorkflowNodeInfo} from '../../../workflows/components/workflow-node-info/workflow-node-info';
Expand Down Expand Up @@ -217,7 +218,9 @@ export class ArchivedWorkflowDetails extends BasePage<RouteComponentProps<any>,
)}
<SlidingPanel isShown={!!this.sidePanel} onClose={() => (this.sidePanel = null)}>
{this.sidePanel === 'yaml' && <WorkflowYamlViewer workflow={this.state.workflow} selectedNode={this.node} />}
{this.sidePanel === 'logs' && <WorkflowLogsViewer workflow={this.state.workflow} nodeId={this.nodeId} container={this.container} archived={true} />}
{this.sidePanel === 'logs' && (
<WorkflowLogsViewer workflow={this.state.workflow} initialPodName={this.podName} nodeId={this.nodeId} container={this.container} archived={true} />
)}
{this.sidePanel === 'resubmit' && (
<ResourceEditor<Workflow>
editing={true}
Expand Down Expand Up @@ -246,6 +249,14 @@ export class ArchivedWorkflowDetails extends BasePage<RouteComponentProps<any>,
return this.nodeId && this.state.workflow.status.nodes[this.nodeId];
}

private get podName() {
if (this.nodeId && this.state.workflow) {
const workflowName = this.state.workflow.metadata.name;
const {name, templateName} = this.node;
return Utils.getPodName(workflowName, name, templateName, this.nodeId);
}
}

private deleteArchivedWorkflow() {
if (!confirm('Are you sure you want to delete this archived workflow?\nThere is no undo.')) {
return;
Expand Down
40 changes: 40 additions & 0 deletions ui/src/app/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {NODE_PHASE} from '../../models';

const managedNamespaceKey = 'managedNamespace';
const currentNamespaceKey = 'current_namespace';
const maxK8sResourceNameLength = 253;
const k8sNamingHashLength = 10;

export const Utils = {
statusIconClasses(status: string): string {
let classes = [];
Expand Down Expand Up @@ -117,5 +120,42 @@ export const Utils = {
// return a namespace, never return null/undefined, defaults to "default"
getNamespaceWithDefault(namespace: string) {
return this.managedNamespace || namespace || this.currentNamespace || 'default';
},

ensurePodNamePrefixLength(prefix: string): string {
const maxPrefixLength = maxK8sResourceNameLength - k8sNamingHashLength;

if (prefix.length > maxPrefixLength - 1) {
return prefix.substring(0, maxPrefixLength - 1);
}

return prefix;
},

// getPodName returns a deterministic pod name
getPodName(workflowName: string, nodeName: string, templateName: string, nodeID: string): string {
if (workflowName === nodeName) {
return workflowName;
}

let prefix = `${workflowName}-${templateName}`;
prefix = this.ensurePodNamePrefixLength(prefix);

const hash = createFNVHash(nodeName);
return `${prefix}-${hash}`;
}
};

const createFNVHash = (input: string): number => {
const data = new Buffer(input);

let hashint = 2166136261;

/* tslint:disable:no-bitwise */
for (const character of data) {
hashint = hashint ^ character;
hashint += (hashint << 1) + (hashint << 4) + (hashint << 7) + (hashint << 8) + (hashint << 24);
}

return hashint >>> 0;
};
1 change: 1 addition & 0 deletions ui/src/app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"experimentalDecorators": true,
"noUnusedLocals": true,
"declaration": false,
"downlevelIteration": true,
"lib": [
"es2017",
"dom"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as classNames from 'classnames';
import * as React from 'react';
import {useContext, useEffect, useState} from 'react';
import {RouteComponentProps} from 'react-router';
import {execSpec, Link, Workflow} from '../../../../models';
import {execSpec, Link, NodeStatus, Workflow} from '../../../../models';
import {uiUrl} from '../../../shared/base';
import {CostOptimisationNudge} from '../../../shared/components/cost-optimisation-nudge';
import {ErrorNotice} from '../../../shared/components/error-notice';
Expand All @@ -16,6 +16,7 @@ import {historyUrl} from '../../../shared/history';
import {RetryWatch} from '../../../shared/retry-watch';
import {services} from '../../../shared/services';
import {useQueryParams} from '../../../shared/use-query-params';
import {Utils} from '../../../shared/utils';
import * as Operations from '../../../shared/workflow-operations-map';
import {WorkflowOperations} from '../../../shared/workflow-operations-map';
import {WidgetGallery} from '../../../widgets/widget-gallery';
Expand Down Expand Up @@ -224,7 +225,18 @@ export const WorkflowDetails = ({history, location, match}: RouteComponentProps<
}
};


const getPodName = (wf: Workflow, node: NodeStatus, nodeID: string): string => {
if (workflow && node) {
return Utils.getPodName(wf.metadata.name, node.name, node.templateName, node.id);
}

return nodeID;
};

const selectedNode = workflow && workflow.status && workflow.status.nodes && workflow.status.nodes[nodeId];
const podName = getPodName(workflow, selectedNode, nodeId);

return (
<Page
title={'Workflow Details'}
Expand Down Expand Up @@ -292,7 +304,7 @@ export const WorkflowDetails = ({history, location, match}: RouteComponentProps<
{workflow && (
<SlidingPanel isShown={!!sidePanel} onClose={() => setSidePanel(null)}>
{parsedSidePanel.type === 'logs' && (
<WorkflowLogsViewer workflow={workflow} nodeId={parsedSidePanel.nodeId} container={parsedSidePanel.container} archived={false} />
<WorkflowLogsViewer workflow={workflow} initialPodName={podName} nodeId={parsedSidePanel.nodeId} container={parsedSidePanel.container} archived={false} />
)}
{parsedSidePanel.type === 'events' && <EventsPanel namespace={namespace} kind='Pod' name={parsedSidePanel.nodeId} />}
{parsedSidePanel.type === 'share' && <WidgetGallery namespace={namespace} name={name} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import {ErrorNotice} from '../../../shared/components/error-notice';
import {InfoIcon, WarningIcon} from '../../../shared/components/fa-icons';
import {Links} from '../../../shared/components/links';
import {services} from '../../../shared/services';
import {Utils} from '../../../shared/utils';
import {FullHeightLogsViewer} from './full-height-logs-viewer';

interface WorkflowLogsViewerProps {
workflow: models.Workflow;
nodeId?: string;
initialPodName: string;
container: string;
archived: boolean;
}
Expand All @@ -22,8 +24,8 @@ function identity<T>(value: T) {
return () => value;
}

export const WorkflowLogsViewer = ({workflow, nodeId, container, archived}: WorkflowLogsViewerProps) => {
const [podName, setPodName] = useState(nodeId || '');
export const WorkflowLogsViewer = ({workflow, nodeId, initialPodName, container, archived}: WorkflowLogsViewerProps) => {
const [podName, setPodName] = useState(initialPodName || '');
const [selectedContainer, setContainer] = useState(container);
const [grep, setGrep] = useState('');
const [error, setError] = useState<Error>();
Expand Down Expand Up @@ -59,7 +61,11 @@ export const WorkflowLogsViewer = ({workflow, nodeId, container, archived}: Work
const podNames = [{value: '', label: 'All'}].concat(
Object.values(workflow.status.nodes || {})
.filter(x => x.type === 'Pod')
.map(x => ({value: x.id, label: (x.displayName || x.name) + ' (' + x.id + ')'}))
.map(targetNode => {
const {name, id, templateName, displayName} = targetNode;
const targetPodName = Utils.getPodName(workflow.metadata.name, name, templateName, id);
return {value: targetPodName, label: (displayName || name) + ' (' + targetPodName + ')'};
})
);

const node = workflow.status.nodes[nodeId];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {Timestamp} from '../../../shared/components/timestamp';
import {ResourcesDuration} from '../../../shared/resources-duration';
import {services} from '../../../shared/services';
import {getResolvedTemplates} from '../../../shared/template-resolution';
import {Utils} from '../../../shared/utils';

require('./workflow-node-info.scss');

Expand Down Expand Up @@ -78,6 +79,10 @@ const AttributeRows = (props: {attributes: {title: string; value: any}[]}) => (
);

const WorkflowNodeSummary = (props: Props) => {
const {workflow, node} = props;

const podName = Utils.getPodName(workflow.metadata.name, node.name, node.templateName, node.id);

const attributes = [
{title: 'NAME', value: <ClipboardText text={props.node.name} />},
{title: 'TYPE', value: props.node.type},
Expand Down Expand Up @@ -130,7 +135,7 @@ const WorkflowNodeSummary = (props: Props) => {
attributes.splice(
2,
0,
{title: 'POD NAME', value: <ClipboardText text={props.node.id} />},
{title: 'POD NAME', value: <ClipboardText text={podName} />},
{
title: 'HOST NODE NAME',
value: <ClipboardText text={props.node.hostNodeName} />
Expand Down

0 comments on commit 7cdbee0

Please sign in to comment.