Przeglądaj źródła

Merge pull request #390 from porter-dev/beta.3.application-types

stream job status
sunguroku 5 lat temu
rodzic
commit
f45b244f67

+ 2 - 0
dashboard/src/components/ResourceTab.tsx

@@ -253,6 +253,8 @@ const StatusColor = styled.div`
       ? "#4797ff"
       : props.status === "failed" || props.status === "FailedValidation"
       ? "#ed5f85"
+      : props.status === "completed"
+      ? '#00d12a'
       : "#f5cb42"};
   border-radius: 20px;
 `;

+ 9 - 0
dashboard/src/components/StatusIndicator.tsx

@@ -33,6 +33,11 @@ export default class StatusIndicator extends Component<PropsType, StateType> {
       for (var uid in this.props.controllers) {
         let value = this.props.controllers[uid];
         let available = this.getAvailability(value.metadata.kind, value);
+
+        if (value.metadata.kind?.toLowerCase() === "job" && !value.status?.active) {
+          return "completed"
+        }
+
         let progressing = true;
 
         this.props.controllers[uid]?.status?.conditions?.forEach(
@@ -67,6 +72,8 @@ export default class StatusIndicator extends Component<PropsType, StateType> {
         return c.status.readyReplicas == c.status.replicas;
       case "daemonset":
         return c.status.numberAvailable == c.status.desiredNumberScheduled;
+      case "job":
+        return c.status.active
     }
   };
 
@@ -97,6 +104,8 @@ const StatusColor = styled.div`
       ? "#4797ff"
       : props.status === "failed"
       ? "#ed5f85"
+      : props.status === "completed"
+      ? '#00d12a'
       : "#f5cb42"};
   border-radius: 20px;
   margin-right: 16px;

+ 13 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -288,7 +288,11 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
       case "metrics":
         return <MetricsSection currentChart={chart} />;
       case "status":
-        return <StatusSection currentChart={chart} selectors={podSelectors} />;
+        let controller_uid = Object.keys(this.state.controllers)[0]
+        if (chart.chart.metadata.name == "job") {
+          return <StatusSection currentChart={chart} selectors={[`job-name=${chart.name}-job,controller-uid=${controller_uid}`]} />;          
+        }
+        return <StatusSection currentChart={chart} />;
       case "settings":
         return (
           <SettingsSection
@@ -453,6 +457,11 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
       for (var uid in this.state.controllers) {
         let value = this.state.controllers[uid];
         let available = this.getAvailability(value.metadata.kind, value);
+
+        if (value.metadata.kind?.toLowerCase() == "job" && !value.status?.active) {
+          return "completed";
+        }
+
         let progressing = true;
 
         this.state.controllers[uid]?.status?.conditions?.forEach(
@@ -487,6 +496,8 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
         return c.status.readyReplicas == c.status.replicas;
       case "daemonset":
         return c.status.numberAvailable == c.status.desiredNumberScheduled;
+      case "job":
+        return c.status.active
     }
   };
 
@@ -639,6 +650,7 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
     let { currentChart, setCurrentChart } = this.props;
     let chart = currentChart;
     let status = this.getChartStatus(chart.info.status);
+
     return (
       <>
         <CloseOverlay onClick={() => setCurrentChart(null)} />

+ 19 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/ControllerTab.tsx

@@ -9,6 +9,7 @@ type PropsType = {
   controller: any;
   selectedPod: any;
   selectPod: Function;
+  selectors: any;
   isLast?: boolean;
   isFirst?: boolean;
   setPodError: (x: string) => void;
@@ -46,6 +47,10 @@ export default class ControllerTab extends Component<PropsType, StateType> {
     }
     selectors.push(selector);
 
+    if (selectors.length == 0 && this.props.selectors) {
+      selectors = this.props.selectors;
+    }
+    
     api
       .getMatchingPods(
         "<token>",
@@ -105,6 +110,8 @@ export default class ControllerTab extends Component<PropsType, StateType> {
           c.status?.numberAvailable || 0,
           c.status?.desiredNumberScheduled || 0,
         ];
+      case "job":
+        return [1, 1]
     }
   };
 
@@ -147,6 +154,13 @@ export default class ControllerTab extends Component<PropsType, StateType> {
     let { controller, selectedPod, isLast, selectPod, isFirst } = this.props;
     let [available, total] = this.getAvailability(controller.kind, controller);
     let status = available == total ? "running" : "waiting";
+
+    if (controller.kind?.toLowerCase() == "job" && !controller.status.active) {
+      status = "completed"
+    }
+
+    console.log("STATUS", status)
+
     return (
       <ResourceTab
         label={controller.kind}
@@ -157,6 +171,9 @@ export default class ControllerTab extends Component<PropsType, StateType> {
       >
         {this.state.raw.map((pod, i) => {
           let status = this.getPodStatus(pod.status);
+          if (controller.kind?.toLowerCase() == "job" && !controller.status.active) {
+            status = "completed"
+          }
           return (
             <Tab
               key={pod.metadata?.name}
@@ -260,6 +277,8 @@ const StatusColor = styled.div`
       ? "#4797ff"
       : props.status === "failed"
       ? "#ed5f85"
+      : props.status === "completed"
+      ? '#00d12a'
       : "#f5cb42"};
   border-radius: 20px;
 `;

+ 9 - 0
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/Logs.tsx

@@ -40,6 +40,15 @@ export default class Logs extends Component<PropsType, StateType> {
     if (!selectedPod?.metadata?.name) {
       return <Message>Please select a pod to view its logs.</Message>;
     }
+
+    if (selectedPod?.status.phase === "Succeeded") {
+      return (
+        <Message>
+          ⌛ This job has been completed. You can now delete this job.
+        </Message>
+      )
+    }
+
     if (this.state.logs.length == 0) {
       return (
         <Message>

+ 3 - 2
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/StatusSection.tsx

@@ -10,7 +10,7 @@ import Logs from "./Logs";
 import ControllerTab from "./ControllerTab";
 
 type PropsType = {
-  selectors: string[];
+  selectors?: string[];
   currentChart: ChartType;
 };
 
@@ -56,6 +56,7 @@ export default class StatusSection extends Component<PropsType, StateType> {
           key={c.metadata.uid}
           selectedPod={this.state.selectedPod}
           selectPod={this.selectPod.bind(this)}
+          selectors={this.props.selectors}
           controller={c}
           isLast={i === this.state.controllers.length - 1}
           isFirst={i === 0}
@@ -92,7 +93,7 @@ export default class StatusSection extends Component<PropsType, StateType> {
   };
 
   componentDidMount() {
-    const { selectors, currentChart } = this.props;
+    const { currentChart } = this.props;
     let { currentCluster, currentProject, setCurrentError } = this.context;
 
     api

+ 9 - 0
internal/kubernetes/agent.go

@@ -110,6 +110,15 @@ func (a *Agent) GetDaemonSet(c grapher.Object) (*appsv1.DaemonSet, error) {
 	)
 }
 
+// GetJob gets the job by name and namespace
+func (a *Agent) GetJob(c grapher.Object) (*batchv1.Job, error) {
+	return a.Clientset.BatchV1().Jobs(c.Namespace).Get(
+		context.TODO(),
+		c.Name,
+		metav1.GetOptions{},
+	)
+}
+
 // GetPodsByLabel retrieves pods with matching labels
 func (a *Agent) GetPodsByLabel(selector string) (*v1.PodList, error) {
 	// Search in all namespaces for matching pods

+ 10 - 0
server/api/release_handler.go

@@ -369,6 +369,16 @@ func (app *App) HandleGetReleaseControllers(w http.ResponseWriter, r *http.Reque
 				return
 			}
 
+			rc.Kind = c.Kind
+			retrievedControllers = append(retrievedControllers, rc)
+		case "Job":
+			rc, err := k8sAgent.GetJob(c)
+
+			if err != nil {
+				app.handleErrorDataRead(err, w)
+				return
+			}
+
 			rc.Kind = c.Kind
 			retrievedControllers = append(retrievedControllers, rc)
 		}