You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by bb...@apache.org on 2022/03/09 03:15:47 UTC

[airflow] branch mapped-task-drawer updated: task instance links

This is an automated email from the ASF dual-hosted git repository.

bbovenzi pushed a commit to branch mapped-task-drawer
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/mapped-task-drawer by this push:
     new 4d00224  task instance links
4d00224 is described below

commit 4d002242bea12bdac7601abc078de06b549131d9
Author: Brent Bovenzi <br...@gmail.com>
AuthorDate: Tue Mar 8 22:14:44 2022 -0500

    task instance links
---
 airflow/www/static/js/tree/details/Header.jsx      |  6 +--
 .../www/static/js/tree/details/content/DagRun.jsx  |  8 ++++
 .../js/tree/details/content/TaskInstance.jsx       | 45 +++++++++++++++++++++-
 airflow/www/templates/airflow/dag.html             |  3 +-
 4 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/airflow/www/static/js/tree/details/Header.jsx b/airflow/www/static/js/tree/details/Header.jsx
index 2982a4e..dd0894c 100644
--- a/airflow/www/static/js/tree/details/Header.jsx
+++ b/airflow/www/static/js/tree/details/Header.jsx
@@ -57,20 +57,20 @@ const Header = ({
 
   return (
     <Breadcrumb>
-      <BreadcrumbItem isCurrentPage={!runId && !taskId}>
+      <BreadcrumbItem isCurrentPage={!runId && !taskId} mt="15px">
         <BreadcrumbLink onClick={() => onSelect({})}>
           <LabelValue label="DAG" value={dagId} />
         </BreadcrumbLink>
       </BreadcrumbItem>
       {runId && (
-        <BreadcrumbItem isCurrentPage={runId && !taskId}>
+        <BreadcrumbItem isCurrentPage={runId && !taskId} mt="15px">
           <BreadcrumbLink onClick={() => onSelect({ runId, dagRun })}>
             <LabelValue label="Run" value={runLabel} />
           </BreadcrumbLink>
         </BreadcrumbItem>
       )}
       {taskId && (
-        <BreadcrumbItem isCurrentPage>
+        <BreadcrumbItem isCurrentPage mt="15px">
           <BreadcrumbLink>
             <LabelValue label="Task" value={taskId} />
           </BreadcrumbLink>
diff --git a/airflow/www/static/js/tree/details/content/DagRun.jsx b/airflow/www/static/js/tree/details/content/DagRun.jsx
index b47907b..fe2c204 100644
--- a/airflow/www/static/js/tree/details/content/DagRun.jsx
+++ b/airflow/www/static/js/tree/details/content/DagRun.jsx
@@ -25,6 +25,7 @@ import {
   Text,
   Box,
   Button,
+  Link,
 } from '@chakra-ui/react';
 import { MdPlayArrow } from 'react-icons/md';
 
@@ -40,12 +41,19 @@ const DagRun = ({
   const { mutate: markFailed } = useMarkFailedRun(dagId, runId);
   const { mutate: markSuccess } = useMarkSuccessRun(dagId, runId);
 
+  const params = new URLSearchParams({
+    dag_id: dagId,
+    run_id: runId,
+  }).toString();
+  const detailsLink = `/dagrun_details?${params}`;
+
   return (
     <Box fontSize="12px" py="4px">
       <Flex justifyContent="space-evenly">
         <Button onClick={onClear}>Clear</Button>
         <Button onClick={markFailed} colorScheme="red">Mark Failed</Button>
         <Button onClick={markSuccess} colorScheme="green">Mark Success</Button>
+        <Button as={Link} variant="outline" href={detailsLink}>More Details</Button>
       </Flex>
       <Text>
         <Text as="strong">Status:</Text>
diff --git a/airflow/www/static/js/tree/details/content/TaskInstance.jsx b/airflow/www/static/js/tree/details/content/TaskInstance.jsx
index 0c0a21e..f1ed08f 100644
--- a/airflow/www/static/js/tree/details/content/TaskInstance.jsx
+++ b/airflow/www/static/js/tree/details/content/TaskInstance.jsx
@@ -23,14 +23,28 @@ import React from 'react';
 import {
   Text,
   Box,
+  Button,
+  Flex,
+  Link,
 } from '@chakra-ui/react';
-import { finalStatesMap } from '../../../utils';
+import { finalStatesMap, getMetaValue } from '../../../utils';
 
 import { formatDateTime, getDuration, formatDuration } from '../../../datetime_utils';
 
+const isK8sExecutor = getMetaValue('k8s_or_k8scelery_executor') === 'True';
+
 const TaskInstance = ({
   instance: {
-    duration, operator, startDate, endDate, state, taskId, runId, mappedStates,
+    dagId,
+    duration,
+    operator,
+    startDate,
+    endDate,
+    state,
+    taskId,
+    runId,
+    mappedStates,
+    executionDate,
   },
   task,
 }) => {
@@ -83,8 +97,35 @@ const TaskInstance = ({
 
   const taskIdTitle = isGroup ? 'Task Group Id: ' : 'Task Id: ';
 
+  const params = new URLSearchParams({
+    dag_id: dagId,
+    task_id: task.id,
+    execution_date: executionDate,
+  }).toString();
+  const detailsLink = `/task?${params}`;
+  const renderedLink = `/rendered-templates?${params}`;
+  const logLink = `/log?${params}`;
+  const k8sLink = `/rendered-k8s?${params}`;
+  const listParams = new URLSearchParams({
+    _flt_3_dag_id: dagId,
+    _flt_3_task_id: taskId,
+    _oc_TaskInstanceModelView: executionDate,
+  });
+  const allInstancesLink = `/taskinstance/list?${listParams}`;
+
   return (
     <Box fontSize="12px" py="4px">
+      {!isGroup && !task.isMapped && (
+        <Flex justifyContent="space-evenly">
+          <Button as={Link} variant="outline" href={detailsLink}>Instance Details</Button>
+          <Button as={Link} variant="outline" href={renderedLink}>Rendered Template</Button>
+          {isK8sExecutor && (
+            <Button as={Link} variant="outline" href={k8sLink}>K8s Pod Spec</Button>
+          )}
+          <Button as={Link} variant="outline" href={logLink}>Log</Button>
+          <Button as={Link} variant="outline" href={allInstancesLink}>All Instances</Button>
+        </Flex>
+      )}
       {task.tooltip && (
         <Text>{task.tooltip}</Text>
       )}
diff --git a/airflow/www/templates/airflow/dag.html b/airflow/www/templates/airflow/dag.html
index 0f3387a..335a26b 100644
--- a/airflow/www/templates/airflow/dag.html
+++ b/airflow/www/templates/airflow/dag.html
@@ -40,6 +40,7 @@
   <meta name="tree_data" content="{{ url_for('Airflow.tree_data') }}">
   <meta name="is_paused" content="{{ dag_is_paused }}">
   <meta name="csrf_token" content="{{ csrf_token() }}">
+  <meta name="k8s_or_k8scelery_executor" content="{{ k8s_or_k8scelery_executor }}">
   {% if dag_model is defined and dag_model.next_dagrun_create_after is defined and dag_model.next_dagrun_create_after is not none %}
     <meta name="next_dagrun_create_after" content="{{ dag_model.next_dagrun_create_after }}">
     <meta name="next_dagrun_data_interval_start" content="{{ dag_model.next_dagrun_data_interval_start }}">
@@ -413,7 +414,7 @@
             </span>
           </div>
           <hr style="margin-bottom: 8px;">
-          <a id="btn_dagrun_details" class="btn" data-base-url="{{ url_for('Airflow.dagrun_details', redirect_url=request.base_url) }}">
+          <a id="btn_dagrun_details" class="btn" data-base-url="{{ url_for('Airflow.dagrun_details') }}">
             DAG Run details
           </a>
         </div>