Browse Source

Merge pull request #407 from porter-dev/master

Recent changes to dev
abelanger5 5 years ago
parent
commit
40b012988b

+ 2 - 1
.github/workflows/dev.yaml

@@ -1,4 +1,4 @@
-name: Deploy to production
+name: Deploy to dev
 on:
   push:
     branches:
@@ -31,6 +31,7 @@ jobs:
           FEEDBACK_ENDPOINT=${{secrets.FEEDBACK_ENDPOINT}}
           POSTHOG_API_KEY=${{secrets.POSTHOG_API_KEY}}
           POSTHOG_HOST=${{secrets.POSTHOG_HOST}}
+          APPLICATION_CHART_REPO_URL=${{secrets.APPLICATION_CHART_REPO_URL}}
           EOL
       - name: Build
         run: |

+ 1 - 1
.github/workflows/staging.yaml

@@ -1,4 +1,4 @@
-name: Build, Push to GCR.
+name: Deploy to staging
 on:
   push:
     branches:

File diff suppressed because it is too large
+ 1 - 10378
dashboard/package-lock.json


+ 1 - 1
dashboard/src/components/SaveButton.tsx

@@ -116,7 +116,7 @@ const ButtonWrapper = styled.div`
       `;
     }
     return `
-      bottom: 0;
+      bottom: 5px;
       right: 0;
     `;
   }}

+ 2 - 10
dashboard/src/components/StatusIndicator.tsx

@@ -33,14 +33,6 @@ 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(
@@ -75,8 +67,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;
+      case "cronjob":
+        return 1
     }
   };
 

+ 1 - 1
dashboard/src/components/TabRegion.tsx

@@ -77,7 +77,7 @@ const Div = styled.div`
 `;
 
 const TabContents = styled.div`
-  height: calc(100% - 80px);
+  height: calc(100% - 65px);
 `;
 
 const Gap = styled.div`

+ 2 - 1
dashboard/src/components/TabSelector.tsx

@@ -12,6 +12,7 @@ type PropsType = {
   setCurrentTab: (value: string) => void;
   addendum?: any;
   color?: string;
+  noBuffer?: boolean;
 };
 
 type StateType = {};
@@ -45,7 +46,7 @@ export default class TabSelector extends Component<PropsType, StateType> {
         <TabWrapper>
           {this.renderTabList()}
           <Tab lastItem={true} highlight={null}>
-            <Buffer />
+            {this.props.noBuffer ? null : <Buffer />}
           </Tab>
         </TabWrapper>
         {this.props.addendum}

+ 1 - 1
dashboard/src/components/repo-selector/ActionDetails.tsx

@@ -147,7 +147,7 @@ export default class ActionDetails extends Component<PropsType, StateType> {
             href="https://docs.getporter.dev/docs/auto-deploy-requirements#cicd-with-github-actions"
             target="_blank"
           >
-            Learn More
+            Learn more
           </Highlight>
         </SubtitleAlt>
         <Br />

+ 1 - 4
dashboard/src/components/repo-selector/RepoList.tsx

@@ -123,11 +123,10 @@ export default class ActionConfEditor extends Component<PropsType, StateType> {
         <LoadingWrapper>
           No connected Github repos found. You can
           <A
-            padRight={true}
             href={`/api/oauth/projects/${this.context.currentProject.id}/github?redirected=true`}
           >
             log in with GitHub
-          </A>{" "}
+          </A>
           .
         </LoadingWrapper>
       );
@@ -254,6 +253,4 @@ const A = styled.a`
   text-decoration: underline;
   margin-left: 5px;
   cursor: pointer;
-  padding-right: ${(props: { padRight?: boolean }) =>
-    props.padRight ? "5px" : ""};
 `;

+ 7 - 14
dashboard/src/main/home/cluster-dashboard/expanded-chart/ExpandedChart.tsx

@@ -107,6 +107,7 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
 
     // don't retrieve controllers for chart that failed to even deploy.
     if (chart.info.status == "failed") return;
+
     // TODO: properly promisify
     await new Promise((next: (res?: any) => void) => {
       api
@@ -288,14 +289,16 @@ export default class ExpandedChart extends Component<PropsType, StateType> {
       case "metrics":
         return <MetricsSection currentChart={chart} />;
       case "status":
-        let controller_uid = Object.keys(this.state.controllers)[0];
+        let activeJobs = Object.values(this.state.controllers)[0]?.status.active;
+        let selectors = activeJobs?.map((job: any) => {
+          return `job-name=${job.name},controller-uid=${job.uid}`
+        })
+
         if (chart.chart.metadata.name == "job") {
           return (
             <StatusSection
               currentChart={chart}
-              selectors={[
-                `job-name=${chart.name}-job,controller-uid=${controller_uid}`,
-              ]}
+              selectors={selectors}
             />
           );
         }
@@ -458,14 +461,6 @@ 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(
@@ -500,8 +495,6 @@ 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;
     }
   };
 

+ 147 - 155
dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/MetricsSection.tsx

@@ -2,11 +2,13 @@ import React, { Component } from "react";
 import styled from "styled-components";
 import ParentSize from "@visx/responsive/lib/components/ParentSize";
 
+import settings from "assets/settings.svg";
 import api from "shared/api";
 import { Context } from "shared/Context";
 import { ChartType, StorageType } from "shared/types";
 
 import TabSelector from "components/TabSelector";
+import SelectRow from "components/values-form/SelectRow";
 import AreaChart, { MetricsData } from "./AreaChart";
 
 type PropsType = {
@@ -14,9 +16,9 @@ type PropsType = {
 };
 
 type StateType = {
-  controllers: any[];
+  controllerOptions: any[];
   selectedController: any;
-  pods: string[];
+  pods: any[];
   selectedPod: string;
   selectedRange: string;
   selectedMetric: string;
@@ -25,6 +27,7 @@ type StateType = {
   podDropdownExpanded: boolean;
   dropdownExpanded: boolean;
   data: MetricsData[];
+  showMetricsSettings: boolean;
 };
 
 type MetricsCPUDataResponse = {
@@ -67,9 +70,9 @@ const secondsBeforeNow: { [range: string]: number } = {
 
 export default class MetricsSection extends Component<PropsType, StateType> {
   state = {
-    pods: [] as string[],
+    pods: [] as any[],
     selectedPod: "",
-    controllers: [] as any[],
+    controllerOptions: [] as any[],
     selectedController: null as any,
     selectedRange: "1H",
     selectedMetric: "cpu",
@@ -78,6 +81,7 @@ export default class MetricsSection extends Component<PropsType, StateType> {
     podDropdownExpanded: false,
     controllerDropdownExpanded: false,
     data: [] as MetricsData[],
+    showMetricsSettings: false,
   };
 
   componentDidMount() {
@@ -101,18 +105,23 @@ export default class MetricsSection extends Component<PropsType, StateType> {
       )
       .then((res) => {
         // TODO -- check at least one controller returned
+        let controllerOptions = [] as any[];
+        res.data.map((controller: any) => {
+          let name = controller?.metadata?.name;
+          controllerOptions.push({ value: controller, label: name });
+        });
 
         // iterate through the controllers to get the list of pods
         this.setState({
-          controllers: res.data,
-          selectedController: res.data[0],
+          controllerOptions,
+          selectedController: controllerOptions[0].value,
         });
 
         this.getPods();
       })
       .catch((err) => {
         setCurrentError(JSON.stringify(err));
-        this.setState({ controllers: [] });
+        this.setState({ controllerOptions: [] as any[] });
       });
   }
 
@@ -153,7 +162,9 @@ export default class MetricsSection extends Component<PropsType, StateType> {
     var end = Math.round(d.getTime() / 1000);
     var start = end - secondsBeforeNow[this.state.selectedRange];
 
-    let pods = this.state.pods;
+    let pods = this.state.pods.map((pod: any) => {
+      return pod.value;
+    });
 
     if (this.state.selectedPod != "All") {
       pods = [this.state.selectedPod];
@@ -166,7 +177,7 @@ export default class MetricsSection extends Component<PropsType, StateType> {
           cluster_id: currentCluster.id,
           metric: kind,
           shouldsum: shouldsum,
-          pods: pods,
+          pods,
           namespace: currentChart.namespace,
           startrange: start,
           endrange: end,
@@ -275,8 +286,10 @@ export default class MetricsSection extends Component<PropsType, StateType> {
         }
       )
       .then((res) => {
-        let pods = res?.data?.map((pod: any) => {
-          return pod?.metadata?.name;
+        let pods = [{ value: "All", label: "All (Summed)" }] as any[];
+        res?.data?.forEach((pod: any) => {
+          let name = pod?.metadata?.name;
+          pods.push({ value: name, label: name });
         });
 
         this.setState({ pods, selectedPod: "All" });
@@ -309,89 +322,6 @@ export default class MetricsSection extends Component<PropsType, StateType> {
     }
   };
 
-  renderPodDropdown = () => {
-    if (this.state.podDropdownExpanded) {
-      return (
-        <>
-          <DropdownOverlay
-            onClick={() => this.setState({ podDropdownExpanded: false })}
-          />
-          <Dropdown
-            dropdownWidth="400px"
-            dropdownMaxHeight="200px"
-            onClick={() => this.setState({ podDropdownExpanded: false })}
-          >
-            {this.renderPodOptionList()}
-          </Dropdown>
-        </>
-      );
-    }
-  };
-
-  renderPodOptionList = () => {
-    let allPod = [
-      <Option
-        key={0}
-        selected={"All" === this.state.selectedPod}
-        onClick={() => this.setState({ selectedPod: "All" })}
-        lastItem={false}
-      >
-        All (summed)
-      </Option>,
-    ];
-
-    let podOptions = this.state.pods.map((option: string, i: number) => {
-      return (
-        <Option
-          key={i + 1}
-          selected={option === this.state.selectedPod}
-          onClick={() => this.setState({ selectedPod: option })}
-          lastItem={i === this.state.pods.length - 1}
-        >
-          {option}
-        </Option>
-      );
-    });
-
-    return allPod.concat(podOptions);
-  };
-
-  renderControllerDropdown = () => {
-    if (this.state.controllerDropdownExpanded) {
-      return (
-        <>
-          <DropdownOverlay
-            onClick={() => this.setState({ controllerDropdownExpanded: false })}
-          />
-          <Dropdown
-            dropdownWidth="300px"
-            dropdownMaxHeight="200px"
-            onClick={() => this.setState({ controllerDropdownExpanded: false })}
-          >
-            {this.renderControllerOptionList()}
-          </Dropdown>
-        </>
-      );
-    }
-  };
-
-  renderControllerOptionList = () => {
-    return this.state.controllers.map((controller: any, i: number) => {
-      let name = controller?.metadata?.name;
-
-      return (
-        <Option
-          key={i}
-          selected={name === this.state.selectedController?.metadata?.name}
-          onClick={() => this.setState({ selectedController: controller })}
-          lastItem={i === this.state.controllers.length - 1}
-        >
-          {name}
-        </Option>
-      );
-    });
-  };
-
   renderOptionList = () => {
     let metricOptions = [
       { value: "cpu", label: "CPU Utilization (vCPUs)" },
@@ -419,66 +349,87 @@ export default class MetricsSection extends Component<PropsType, StateType> {
     );
   };
 
+  renderMetricsSettings = () => {
+    if (this.state.showMetricsSettings && true) {
+      return (
+        <>
+          <DropdownOverlay
+            onClick={() => this.setState({ showMetricsSettings: false })}
+          />
+          <DropdownAlt dropdownWidth="330px" dropdownMaxHeight="300px">
+            <Label>Additional Settings</Label>
+            <SelectRow
+              label="Target Controller"
+              value={this.state.selectedController}
+              setActiveValue={(x: any) =>
+                this.setState({ selectedController: x })
+              }
+              options={this.state.controllerOptions}
+              width="100%"
+            />
+            <SelectRow
+              label="Target Pod"
+              value={this.state.selectedPod}
+              setActiveValue={(x: any) => this.setState({ selectedPod: x })}
+              options={this.state.pods}
+              width="100%"
+            />
+          </DropdownAlt>
+        </>
+      );
+    }
+  };
+
   render() {
     return (
       <StyledMetricsSection>
+        <MetricsHeader>
+          <Flex>
+            <MetricSelector
+              onClick={() =>
+                this.setState({
+                  dropdownExpanded: !this.state.dropdownExpanded,
+                })
+              }
+            >
+              <MetricsLabel>{this.state.selectedMetricLabel}</MetricsLabel>
+              <i className="material-icons">arrow_drop_down</i>
+              {this.renderDropdown()}
+            </MetricSelector>
+            <Relative>
+              <IconWrapper
+                onClick={() => this.setState({ showMetricsSettings: true })}
+              >
+                <SettingsIcon src={settings} />
+              </IconWrapper>
+              {this.renderMetricsSettings()}
+            </Relative>
+          </Flex>
+          <RangeWrapper>
+            <TabSelector
+              noBuffer={true}
+              options={[
+                { value: "1H", label: "1H" },
+                { value: "6H", label: "6H" },
+                { value: "1D", label: "1D" },
+                { value: "1M", label: "1M" },
+              ]}
+              currentTab={this.state.selectedRange}
+              setCurrentTab={(x: string) => this.setState({ selectedRange: x })}
+            />
+          </RangeWrapper>
+        </MetricsHeader>
         <ParentSize>
           {({ width, height }) => (
             <AreaChart
               data={this.state.data}
               width={width}
-              height={height}
+              height={height - 10}
               resolution={this.state.selectedRange}
-              margin={{ top: 60, right: -40, bottom: 0, left: 50 }}
+              margin={{ top: 40, right: -40, bottom: 0, left: 50 }}
             />
           )}
         </ParentSize>
-        <MetricSelector
-          onClick={() =>
-            this.setState({ dropdownExpanded: !this.state.dropdownExpanded })
-          }
-        >
-          <MetricsLabel>{this.state.selectedMetricLabel}</MetricsLabel>
-          <i className="material-icons">arrow_drop_down</i>
-          {this.renderDropdown()}
-        </MetricSelector>
-        <ControllerSelector
-          onClick={() =>
-            this.setState({
-              controllerDropdownExpanded: !this.state
-                .controllerDropdownExpanded,
-            })
-          }
-        >
-          <MetricsLabel>
-            {this.state.selectedController?.metadata?.name}
-          </MetricsLabel>
-          <i className="material-icons">arrow_drop_down</i>
-          {this.renderControllerDropdown()}
-        </ControllerSelector>
-        <PodSelector
-          onClick={() =>
-            this.setState({
-              podDropdownExpanded: !this.state.podDropdownExpanded,
-            })
-          }
-        >
-          <MetricsLabel>{this.state.selectedPod}</MetricsLabel>
-          <i className="material-icons">arrow_drop_down</i>
-          {this.renderPodDropdown()}
-        </PodSelector>
-        <RangeWrapper>
-          <TabSelector
-            options={[
-              { value: "1H", label: "1H" },
-              { value: "6H", label: "6H" },
-              { value: "1D", label: "1D" },
-              { value: "1M", label: "1M" },
-            ]}
-            currentTab={this.state.selectedRange}
-            setCurrentTab={(x: string) => this.setState({ selectedRange: x })}
-          />
-        </RangeWrapper>
       </StyledMetricsSection>
     );
   }
@@ -486,6 +437,51 @@ export default class MetricsSection extends Component<PropsType, StateType> {
 
 MetricsSection.contextType = Context;
 
+const Label = styled.div`
+  font-weight: bold;
+`;
+
+const Relative = styled.div`
+  position: relative;
+`;
+
+const IconWrapper = styled.div`
+  display: flex;
+  position: relative;
+  align-items: center;
+  justify-content: center;
+  margin-top: 2px;
+  border-radius: 30px;
+  height: 25px;
+  width: 25px;
+  margin-left: 8px;
+  cursor: pointer;
+  :hover {
+    background: #ffffff22;
+  }
+`;
+
+const SettingsIcon = styled.img`
+  opacity: 0.4;
+  width: 20px;
+  height: 20px;
+  margin-left: -1px;
+  margin-bottom: -2px;
+`;
+
+const Flex = styled.div`
+  display: flex;
+  align-items: center;
+`;
+
+const MetricsHeader = styled.div`
+  width: 100%;
+  display: flex;
+  align-items: center;
+  overflow: visible;
+  justify-content: space-between;
+`;
+
 const DropdownOverlay = styled.div`
   position: fixed;
   width: 100%;
@@ -533,7 +529,12 @@ const Dropdown = styled.div`
   z-index: 999;
   overflow-y: auto;
   margin-bottom: 20px;
-  box-shadow: 0 4px 8px 0px #00000088;
+  box-shadow: 0px 4px 10px 0px #00000088;
+`;
+
+const DropdownAlt = styled(Dropdown)`
+  padding: 20px 20px 7px;
+  overflow: visible;
 `;
 
 const RangeWrapper = styled.div`
@@ -542,15 +543,14 @@ const RangeWrapper = styled.div`
   right: 0;
   font-weight: bold;
   width: 156px;
+  margin-top: -8px;
 `;
 
 const MetricSelector = styled.div`
   font-size: 13px;
   font-weight: 500;
+  position: relative;
   color: #ffffff;
-  position: absolute;
-  top: 10px;
-  left: 0;
   display: flex;
   align-items: center;
   cursor: pointer;
@@ -575,19 +575,11 @@ const MetricsLabel = styled.div`
   max-width: 200px;
 `;
 
-const ControllerSelector = styled(MetricSelector)`
-  left: 230px;
-`;
-
-const PodSelector = styled(MetricSelector)`
-  left: 490px;
-`;
-
 const StyledMetricsSection = styled.div`
   width: 100%;
   height: 100%;
-  background: #20222700;
   display: flex;
+  flex-direction: column;
   position: relative;
   font-size: 13px;
   border-radius: 5px;

+ 7 - 14
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/ControllerTab.tsx

@@ -47,7 +47,7 @@ export default class ControllerTab extends Component<PropsType, StateType> {
     }
     selectors.push(selector);
 
-    if (selectors.length == 0 && this.props.selectors) {
+    if (controller.kind.toLowerCase() == "job" && this.props.selectors) {
       selectors = this.props.selectors;
     }
 
@@ -111,7 +111,8 @@ export default class ControllerTab extends Component<PropsType, StateType> {
           c.status?.desiredNumberScheduled || 0,
         ];
       case "job":
-        return [1, 1];
+        console.log(c)
+        return [1, 1]
     }
   };
 
@@ -121,7 +122,6 @@ export default class ControllerTab extends Component<PropsType, StateType> {
       status?.containerStatuses !== undefined
     ) {
       return status.containerStatuses[0].state.waiting.reason;
-      // return 'waiting'
     } else if (status?.phase === "Pending") {
       return "Pending";
     }
@@ -155,28 +155,21 @@ export default class ControllerTab extends Component<PropsType, StateType> {
     let [available, total] = this.getAvailability(controller.kind, controller);
     let status = available == total ? "running" : "waiting";
 
-    if (controller.kind?.toLowerCase() == "job" && !controller.status.active) {
-      status = "completed";
+    if (controller.kind.toLowerCase() === "job" && this.state.raw.length == 0) {
+      status = "completed" 
     }
 
-    console.log("STATUS", status);
-
     return (
       <ResourceTab
         label={controller.kind}
-        name={controller.metadata.name}
+        // handle CronJob case
+        name={controller.metadata?.name || controller.name}
         status={{ label: status, available, total }}
         isLast={isLast}
         expanded={isFirst}
       >
         {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}

+ 17 - 6
dashboard/src/main/home/cluster-dashboard/expanded-chart/status/StatusSection.tsx

@@ -53,12 +53,13 @@ export default class StatusSection extends Component<PropsType, StateType> {
     return this.state.controllers.map((c, i) => {
       return (
         <ControllerTab
-          key={c.metadata.uid}
+          // handle CronJob case
+          key={c.metadata?.uid || c.uid}
           selectedPod={this.state.selectedPod}
           selectPod={this.selectPod.bind(this)}
-          selectors={this.props.selectors}
+          selectors={this.props.selectors ? [this.props.selectors[i]] : null}
           controller={c}
-          isLast={i === this.state.controllers.length - 1}
+          isLast={i === this.state.controllers?.length - 1}
           isFirst={i === 0}
           setPodError={(x: string) => this.setState({ podError: x })}
         />
@@ -74,7 +75,7 @@ export default class StatusSection extends Component<PropsType, StateType> {
         </NoControllers>
       );
     }
-    if (this.state.controllers.length > 0) {
+    if (this.state.controllers?.length > 0) {
       return (
         <Wrapper>
           <TabWrapper>{this.renderTabs()}</TabWrapper>
@@ -83,6 +84,15 @@ export default class StatusSection extends Component<PropsType, StateType> {
       );
     }
 
+    if (this.props.currentChart.chart.metadata.name === "job") {
+      return (
+        <NoControllers>
+          <i className="material-icons">category</i>
+          There are no jobs currently running.
+        </NoControllers>
+      );
+    }
+
     return (
       <NoControllers>
         <i className="material-icons">category</i>
@@ -110,8 +120,9 @@ export default class StatusSection extends Component<PropsType, StateType> {
           revision: currentChart.version,
         }
       )
-      .then((res) => {
-        this.setState({ controllers: res.data, loading: false });
+      .then((res : any) => {
+        let controllers = currentChart.chart.metadata.name == "job" ? res.data[0]?.status.active : res.data
+        this.setState({controllers, loading: false})
       })
       .catch((err) => {
         setCurrentError(JSON.stringify(err));

+ 11 - 3
dashboard/src/main/home/launch/expanded-template/LaunchTemplate.tsx

@@ -563,6 +563,11 @@ class LaunchTemplate extends Component<PropsType, StateType> {
           <Subtitle>
             Specify the container image you would like to connect to this
             template.
+            <Highlight
+              onClick={() => this.props.history.push("integrations/registry")}
+            >
+              Manage Docker registries
+            </Highlight>
             <Required>*</Required>
           </Subtitle>
           <DarkMatter antiHeight="-4px" />
@@ -610,6 +615,11 @@ class LaunchTemplate extends Component<PropsType, StateType> {
           </CloseButton>
           <Subtitle>
             Provide a repo folder to use as source.
+            <Highlight
+              onClick={() => this.props.history.push("integrations/repo")}
+            >
+              Manage Git repos
+            </Highlight>
             <Required>*</Required>
           </Subtitle>
           <DarkMatter antiHeight="-4px" />
@@ -1019,11 +1029,9 @@ const StyledLaunchTemplate = styled.div`
 
 const Highlight = styled.div`
   color: #8590ff;
-  text-decoration: underline;
+  text-decoration: none;
   margin-left: 5px;
   cursor: pointer;
-  padding-right: ${(props: { padRight?: boolean }) =>
-    props.padRight ? "5px" : ""};
 `;
 
 const StyledSourceBox = styled.div`

+ 1 - 1
internal/helm/grapher/object.go

@@ -67,7 +67,7 @@ func ParseControllers(objs []map[string]interface{}) []Object {
 
 		switch kind.(string) {
 		// Parse for all possible controller types
-		case "Deployment", "StatefulSet", "ReplicaSet", "DaemonSet", "Job":
+		case "Deployment", "StatefulSet", "ReplicaSet", "DaemonSet", "Job", "CronJob":
 			name := getField(obj, "metadata", "name")
 			namespace := getField(obj, "metadata", "namespace")
 

+ 10 - 0
internal/kubernetes/agent.go

@@ -28,6 +28,7 @@ import (
 	"github.com/porter-dev/porter/internal/helm/grapher"
 	appsv1 "k8s.io/api/apps/v1"
 	batchv1 "k8s.io/api/batch/v1"
+	batchv1beta1 "k8s.io/api/batch/v1beta1"
 	v1 "k8s.io/api/core/v1"
 	v1beta1 "k8s.io/api/extensions/v1beta1"
 	"k8s.io/apimachinery/pkg/api/errors"
@@ -119,6 +120,15 @@ func (a *Agent) GetJob(c grapher.Object) (*batchv1.Job, error) {
 	)
 }
 
+// GetCronJob gets the CronJob by name and namespace
+func (a *Agent) GetCronJob(c grapher.Object) (*batchv1beta1.CronJob, error) {
+	return a.Clientset.BatchV1beta1().CronJobs(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

+ 0 - 0
internal/repository/gorm/porter_list_clusters.db-journal


+ 2 - 2
server/api/release_handler.go

@@ -371,8 +371,8 @@ func (app *App) HandleGetReleaseControllers(w http.ResponseWriter, r *http.Reque
 
 			rc.Kind = c.Kind
 			retrievedControllers = append(retrievedControllers, rc)
-		case "Job":
-			rc, err := k8sAgent.GetJob(c)
+		case "CronJob":
+			rc, err := k8sAgent.GetCronJob(c)
 
 			if err != nil {
 				app.handleErrorDataRead(err, w)

+ 2 - 12
services/deploy_init_container/Dockerfile

@@ -1,13 +1,3 @@
 FROM alpine
-CMD ["echo", "-------------------------------------------------------------------\n\
-👋 Hello from Porter!\n\
--------------------------------------------------------------------\n\
--------------------------------------------------------------------\n\
-Your application is being deployed.\n\
-To view build logs, navigate to your connected GitHub repo and     \n\
-select the Actions tab.\n\
--------------------------------------------------------------------\n\
--------------------------------------------------------------------\n\
-For more information, visit:\n\
-https://docs.getporter.dev/docs/setting-up-cicd-1\n\
--------------------------------------------------------------------"]
+ADD start.sh /
+CMD ["sh", "/start.sh"]

+ 18 - 0
services/deploy_init_container/start.sh

@@ -0,0 +1,18 @@
+#!/bin/bash
+
+cat << EOF
+-------------------------------------------------------------------
+👋 Hello from Porter!
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+Your application is being deployed.
+To view build logs, navigate to your connected GitHub repo and     
+select the Actions tab.
+-------------------------------------------------------------------
+-------------------------------------------------------------------
+For more information, visit:
+https://docs.getporter.dev/docs/setting-up-cicd-1
+-------------------------------------------------------------------
+EOF
+
+sleep infinity

Some files were not shown because too many files changed in this diff