Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to rerun and cancel Runs #2418

Merged
merged 1 commit into from
Aug 19, 2022
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
8 changes: 6 additions & 2 deletions packages/components/src/components/StatusIcon/StatusIcon.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const typeClassNames = {
export default function StatusIcon({
DefaultIcon,
hasWarning,
isCustomTask,
reason,
status,
title,
Expand All @@ -73,8 +74,6 @@ export default function StatusIcon({
(status === 'Unknown' && reason === 'Pending')
) {
statusClass = 'pending';
} else if (isRunning(reason, status)) {
statusClass = 'running';
} else if (
status === 'True' ||
(status === 'terminated' && reason === 'Completed')
Expand All @@ -94,6 +93,11 @@ export default function StatusIcon({
(status === 'Unknown' && reason === 'PipelineRunCouldntCancel')
) {
statusClass = 'error';
} else if (
isRunning(reason, status) ||
(isCustomTask && status === 'Unknown')
) {
statusClass = 'running';
}

const Icon = icons[type]?.[statusClass] || DefaultIcon;
Expand Down
35 changes: 34 additions & 1 deletion src/api/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { deleteRequest, get } from './comms';
import { getGenerateNamePrefixForRerun } from '@tektoncd/dashboard-utils';
import deepClone from 'lodash.clonedeep';

import { deleteRequest, get, patch, post } from './comms';
import {
getQueryParams,
getTektonAPI,
Expand Down Expand Up @@ -62,3 +65,33 @@ export function useRun(params, queryConfig) {
webSocketURL
});
}

export function cancelRun({ name, namespace }) {
const payload = [
{ op: 'replace', path: '/spec/status', value: 'RunCancelled' }
];

const uri = getTektonAPI('runs', { name, namespace, version: 'v1alpha1' });
return patch(uri, payload);
}

export function rerunRun(run) {
const { annotations, labels, name, namespace } = run.metadata;

const payload = deepClone(run);
payload.metadata = {
annotations,
generateName: getGenerateNamePrefixForRerun(name),
labels: {
...labels,
'dashboard.tekton.dev/rerunOf': name
},
namespace
};

delete payload.status;
delete payload.spec?.status;

const uri = getTektonAPI('runs', { namespace, version: 'v1alpha1' });
return post(uri, payload).then(({ body }) => body);
}
38 changes: 38 additions & 0 deletions src/api/runs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ import fetchMock from 'fetch-mock';
import * as API from './runs';
import * as utils from './utils';

it('cancelRun', () => {
const name = 'foo';
const namespace = 'foospace';
const returnedRun = { fake: 'Run' };
const payload = [
{ op: 'replace', path: '/spec/status', value: 'RunCancelled' }
];
fetchMock.patch(`end:${name}`, returnedRun);
return API.cancelRun({ name, namespace }).then(response => {
expect(fetchMock.lastOptions()).toMatchObject({
body: JSON.stringify(payload)
});
expect(response).toEqual(returnedRun);
fetchMock.restore();
});
});

it('deleteRun', () => {
const name = 'foo';
const data = { fake: 'Run' };
Expand Down Expand Up @@ -85,3 +102,24 @@ it('useRun', () => {
})
);
});

it('rerunRun', () => {
const filter = 'end:/runs/';
const originalRun = {
metadata: { name: 'fake_run' },
spec: { status: 'fake_status' },
status: 'fake_status'
};
const newRun = { metadata: { name: 'fake_run_rerun' } };
fetchMock.post(filter, { body: newRun, status: 201 });
return API.rerunRun(originalRun).then(data => {
const body = JSON.parse(fetchMock.lastCall(filter)[1].body);
expect(body.metadata.generateName).toMatch(
new RegExp(originalRun.metadata.name)
);
expect(body.status).toBeUndefined();
expect(body.spec.status).toBeUndefined();
expect(data).toEqual(newRun);
fetchMock.restore();
});
});
7 changes: 6 additions & 1 deletion src/containers/Run/Run.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ function getRunStatusIcon(run) {
}
const { reason, status } = getStatus(run);
return (
<StatusIcon DefaultIcon={UndefinedIcon} reason={reason} status={status} />
<StatusIcon
DefaultIcon={UndefinedIcon}
isCustomTask
reason={reason}
status={status}
/>
);
}

Expand Down
65 changes: 60 additions & 5 deletions src/containers/Runs/Runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
ALL_NAMESPACES,
getFilters,
getStatus,
isRunning,
urls,
useTitleSync
} from '@tektoncd/dashboard-utils';
Expand All @@ -43,7 +42,9 @@ import {

import { ListPageLayout } from '..';
import {
cancelRun,
deleteRun,
rerunRun,
useIsReadOnly,
useRuns,
useSelectedNamespace
Expand Down Expand Up @@ -85,7 +86,12 @@ function getRunStatus(run) {
function getRunStatusIcon(run) {
const { reason, status } = getStatus(run);
return (
<StatusIcon DefaultIcon={UndefinedIcon} reason={reason} status={status} />
<StatusIcon
DefaultIcon={UndefinedIcon}
isCustomTask
reason={reason}
status={status}
/>
);
}

Expand Down Expand Up @@ -169,6 +175,17 @@ function Runs({ intl }) {
setToBeDeleted([]);
}

function cancel(run) {
cancelRun({
name: run.metadata.name,
namespace: run.metadata.namespace
});
}

function rerun(run) {
rerunRun(run);
}

function deleteResource(run) {
const { name, namespace: resourceNamespace } = run.metadata;
return deleteRun({ name, namespace: resourceNamespace }).catch(err => {
Expand Down Expand Up @@ -196,7 +213,44 @@ function Runs({ intl }) {
}

return [
// TODO: rerun?
{
action: rerun,
actionText: intl.formatMessage({
id: 'dashboard.rerun.actionText',
defaultMessage: 'Rerun'
}),
disable: resource => !!resource.metadata.labels?.['tekton.dev/pipeline']
},
{
actionText: intl.formatMessage({
id: 'dashboard.cancelTaskRun.actionText',
defaultMessage: 'Stop'
}),
action: cancel,
disable: resource => {
const { status } = getStatus(resource);
return status && status !== 'Unknown';
AlanGreene marked this conversation as resolved.
Show resolved Hide resolved
},
modalProperties: {
heading: intl.formatMessage({
id: 'dashboard.cancelRun.heading',
defaultMessage: 'Stop Run'
}),
primaryButtonText: intl.formatMessage({
id: 'dashboard.cancelRun.primaryText',
defaultMessage: 'Stop Run'
}),
body: resource =>
intl.formatMessage(
{
id: 'dashboard.cancelRun.body',
defaultMessage:
'Are you sure you would like to stop Run {name}?'
},
{ name: resource.metadata.name }
)
}
},
{
actionText: intl.formatMessage({
id: 'dashboard.actions.deleteButton',
Expand All @@ -205,9 +259,10 @@ function Runs({ intl }) {
action: deleteResource,
danger: true,
disable: resource => {
const { reason, status } = getStatus(resource);
return isRunning(reason, status);
const { status } = getStatus(resource);
return status === 'Unknown';
},
hasDivider: true,
modalProperties: {
danger: true,
heading: intl.formatMessage(
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_de.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "PipelineRun stoppen",
"dashboard.cancelPipelineRun.primaryText": "PipelineRun stoppen",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "Stop PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "Stop PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "Allow any currently executing tasks to complete but do not schedule any new non-finally tasks, then execute finally tasks",
"dashboard.cancelRun.body": "Are you sure you would like to stop Run {name}?",
"dashboard.cancelRun.heading": "Stop Run",
"dashboard.cancelRun.primaryText": "Stop Run",
"dashboard.cancelTaskRun.actionText": "Stop",
"dashboard.cancelTaskRun.body": "Are you sure you would like to stop TaskRun {name}?",
"dashboard.cancelTaskRun.heading": "Stop TaskRun",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_es.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "Detener PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "Detener PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "Arrêt de PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "Arrêter PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_it.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "Arresta esecuzione pipeline",
"dashboard.cancelPipelineRun.primaryText": "Arresta esecuzione pipeline",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "PipelineRunを停止",
"dashboard.cancelPipelineRun.primaryText": "PipelineRunを停止",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "停止",
"dashboard.cancelTaskRun.body": "TaskRun {name}を停止してもよろしいですか?",
"dashboard.cancelTaskRun.heading": "TaskRunを停止",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "PipelineRun 중지",
"dashboard.cancelPipelineRun.primaryText": "PipelineRun 중지",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "Parar o PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "Parar o PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "停止 PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "停止 PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "停止",
"dashboard.cancelTaskRun.body": "您确定要停止 TaskRun {name} 吗",
"dashboard.cancelTaskRun.heading": "停止 TaskRun",
Expand Down
3 changes: 3 additions & 0 deletions src/nls/messages_zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"dashboard.cancelPipelineRun.heading": "停止 PipelineRun",
"dashboard.cancelPipelineRun.primaryText": "停止 PipelineRun",
"dashboard.cancelPipelineRun.stoppedRunFinally.description": "",
"dashboard.cancelRun.body": "",
"dashboard.cancelRun.heading": "",
"dashboard.cancelRun.primaryText": "",
"dashboard.cancelTaskRun.actionText": "",
"dashboard.cancelTaskRun.body": "",
"dashboard.cancelTaskRun.heading": "",
Expand Down