Skip to content
This repository was archived by the owner on Dec 20, 2025. It is now read-only.
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import * as React from 'react';
import { get, template, isEmpty, trim } from 'lodash';
import { template, isEmpty } from 'lodash';
import { Observable, Subject } from 'rxjs';

import { IManifestSubscription } from '../IManifestSubscription';
import { IStageManifest, ManifestService } from '../ManifestService';
import { IStageManifest } from '../ManifestService';
import { JobManifestPodLogs } from './JobManifestPodLogs';
import { IManifest } from 'core/domain/IManifest';
import { Application } from 'core/application';
import { IPodNameProvider } from '../PodNameProvider';
import { ManifestReader } from 'core/manifest';

interface IJobStageExecutionLogsProps {
manifest: IStageManifest;
Expand All @@ -15,75 +16,25 @@ interface IJobStageExecutionLogsProps {
application: Application;
externalLink: string;
podNameProvider: IPodNameProvider;
location: string;
}

interface IJobStageExecutionLogsState {
subscription: IManifestSubscription;
manifestId: string;
manifest?: IManifest;
}

export class JobStageExecutionLogs extends React.Component<IJobStageExecutionLogsProps, IJobStageExecutionLogsState> {
public state = {
subscription: { id: '', unsubscribe: () => {}, manifest: {} } as IManifestSubscription,
manifestId: '',
manifest: {} as IManifest,
};

public componentDidMount() {
this.componentDidUpdate(this.props, this.state);
}

public componentWillUnmount() {
this.unsubscribe();
}

private unsubscribe() {
this.state.subscription && this.state.subscription.unsubscribe && this.state.subscription.unsubscribe();
}

public componentDidUpdate(_prevPropds: IJobStageExecutionLogsProps, prevState: IJobStageExecutionLogsState) {
const { manifest } = this.props;
const manifestId = ManifestService.manifestIdentifier(manifest);
if (prevState.manifestId === manifestId) {
return;
}
this.refreshSubscription(manifestId, manifest);
}

private refreshSubscription(manifestId: string, manifest: IStageManifest) {
const subscription = {
id: manifestId,
manifest: this.stageManifestToIManifest(manifest, this.props.deployedName, this.props.account),
unsubscribe: this.subscribeToManifestUpdates(manifest),
};
this.setState({ subscription, manifestId });
}

private subscribeToManifestUpdates(manifest: IStageManifest): () => void {
const params = {
account: this.props.account,
name: this.props.deployedName,
location: manifest.metadata.namespace == null ? '_' : manifest.metadata.namespace,
};
return ManifestService.subscribe(this.props.application, params, (updated: IManifest) => {
const subscription = { ...this.state.subscription, manifest: updated };
this.setState({ subscription });
});
}

private stageManifestToIManifest(manifest: IStageManifest, deployedName: string, account: string): IManifest {
const namespace = get(manifest, ['metadata', 'namespace'], '');
private destroy$ = new Subject();

return {
name: deployedName,
moniker: null,
account,
cloudProvider: 'kubernetes',
location: namespace,
manifest,
status: {},
artifacts: [],
events: [],
};
public componentDidMount() {
const { account, location, deployedName } = this.props;
Observable.from(ManifestReader.getManifest(account, location, deployedName))
.takeUntil(this.destroy$)
.subscribe(manifest => this.setState({ manifest }), () => {});
}

private renderExternalLink(link: string, manifest: IManifest): string {
Expand All @@ -96,11 +47,8 @@ export class JobStageExecutionLogs extends React.Component<IJobStageExecutionLog
}

public render() {
const { manifest } = this.state.subscription;
const { externalLink, podNameProvider } = this.props;
const namespace = trim(
get(manifest, ['manifest', 'metadata', 'annotations', 'artifact.spinnaker.io/location'], ''),
);
const { manifest } = this.state;
const { externalLink, podNameProvider, location, account } = this.props;

// prefer links to external logging platforms
if (!isEmpty(manifest) && externalLink) {
Expand All @@ -112,12 +60,16 @@ export class JobStageExecutionLogs extends React.Component<IJobStageExecutionLog
}

return (
<JobManifestPodLogs
account={manifest.account}
location={namespace}
podNameProvider={podNameProvider}
linkName="Console Output"
/>
<>
{location && (
<JobManifestPodLogs
account={account}
location={location}
podNameProvider={podNameProvider}
linkName="Console Output"
/>
)}
</>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class PreconfiguredJobExecutionDetails extends React.Component<IExecution

if (cloudProvider === 'kubernetes') {
const manifest = get(stage, ['context', 'manifest'], null);
const namespace = get(manifest, ['metadata', 'namespace']);
const namespace = get<string>(stage, ['context', 'jobStatus', 'location']);
const deployedJobs = get(this.props.stage, ['context', 'deploy.jobs']);
const deployedName = get(deployedJobs, namespace, [])[0] || '';
const externalLink = get<string>(this.props.stage, ['context', 'execution', 'logs']);
Expand All @@ -89,6 +89,7 @@ export class PreconfiguredJobExecutionDetails extends React.Component<IExecution
deployedName={deployedName}
account={this.props.stage.context.account}
application={this.props.application}
location={namespace}
externalLink={externalLink}
podNameProvider={podNameProvider}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class RunJobExecutionDetails extends React.Component<IExecutionDetailsSec
const externalLink = get<string>(stage, ['context', 'execution', 'logs']);
const podName = this.mostRecentlyCreatedPodName(get(stage.context, ['jobStatus', 'pods'], []));
const podNameProvider = new DefaultPodNameProvider(podName);
const namespace = get(stage, ['context', 'jobStatus', 'location'], '');

return (
<ExecutionDetailsSection name={name} current={current}>
Expand All @@ -49,23 +50,25 @@ export class RunJobExecutionDetails extends React.Component<IExecutionDetailsSec
<dd>
<AccountTag account={context.account} />
</dd>
{stage.context.jobStatus && stage.context.jobStatus.location && (
<span>
{namespace && (
<>
<dt>Namespace</dt>
<dd>{stage.context.jobStatus.location}</dd>
</span>
<dt>Logs</dt>
<dd>
<JobStageExecutionLogs
manifest={manifest}
deployedName={deployedName}
account={this.props.stage.context.account}
location={namespace}
application={this.props.application}
externalLink={externalLink}
podNameProvider={podNameProvider}
/>
</dd>
</>
)}
<dt>Logs</dt>
<dd>
<JobStageExecutionLogs
manifest={manifest}
deployedName={deployedName}
account={this.props.stage.context.account}
application={this.props.application}
externalLink={externalLink}
podNameProvider={podNameProvider}
/>
</dd>
{!namespace && <div className="well">Collecting additional details...</div>}
</dl>
</div>
</div>
Expand Down