瀏覽代碼

update to handle canceling old deploy

Feroze Mohideen 2 年之前
父節點
當前提交
df50dbb0dc

+ 56 - 1
api/server/handlers/porter_app/create.go

@@ -454,6 +454,12 @@ func createPorterAppDeployEvent(
 	tag string,
 	repo repository.PorterAppEventRepository,
 ) (*models.PorterAppEvent, error) {
+	ctx, span := telemetry.NewSpan(ctx, "create-porter-app-deploy-event")
+	defer span.End()
+
+	// mark all pending deployments from the deploy event of the previous revision as canceled
+	updatePreviousPorterAppDeployEvent(ctx, appID, revision, repo)
+
 	// create a map of service names to their status
 	serviceStatuses := make(map[string]string)
 	for _, serviceName := range serviceNames {
@@ -472,18 +478,67 @@ func createPorterAppDeployEvent(
 		},
 	}
 
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "revision", Value: revision}, telemetry.AttributeKV{Key: "image-tag", Value: tag})
+
 	err := repo.CreateEvent(ctx, &event)
 	if err != nil {
+		err = telemetry.Error(ctx, span, err, "error creating porter app event")
 		return nil, err
 	}
 
 	if event.ID == uuid.Nil {
-		return nil, err
+		return nil, telemetry.Error(ctx, span, nil, "event id for newly created app event is nil")
 	}
 
 	return &event, nil
 }
 
+func updatePreviousPorterAppDeployEvent(ctx context.Context, appID uint, revision int, repo repository.PorterAppEventRepository) {
+	ctx, span := telemetry.NewSpan(ctx, "update-previous-porter-app-deploy-event")
+	defer span.End()
+
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-previous-event", Value: false}, telemetry.AttributeKV{Key: "new-revision", Value: revision})
+	if revision <= 1 {
+		return
+	}
+	revisionFloat64 := float64(revision - 1)
+	matchEvent, err := repo.ReadDeployEventByRevision(ctx, appID, revisionFloat64)
+	if err != nil {
+		_ = telemetry.Error(ctx, span, err, "error reading deploy event by revision")
+		return
+	}
+	if matchEvent.ID == uuid.Nil {
+		_ = telemetry.Error(ctx, span, nil, "could not find previous deploy event")
+		return
+	}
+	if matchEvent.Status != "PROGRESSING" {
+		return
+	}
+	serviceStatus, ok := matchEvent.Metadata["service_status"]
+	if !ok {
+		_ = telemetry.Error(ctx, span, nil, "service status not found in deploy event metadata")
+		return
+	}
+	serviceStatusMap, ok := serviceStatus.(map[string]interface{})
+	if !ok {
+		_ = telemetry.Error(ctx, span, nil, "service status not a map[string]interface")
+		return
+	}
+	for serviceName := range serviceStatusMap {
+		if serviceStatusMap[serviceName] == "PROGRESSING" {
+			serviceStatusMap[serviceName] = "CANCELED"
+		}
+	}
+	matchEvent.Metadata["service_status"] = serviceStatusMap
+	matchEvent.Status = "CANCELED"
+	err = repo.UpdateEvent(ctx, &matchEvent)
+	if err != nil {
+		_ = telemetry.Error(ctx, span, err, "error updating deploy event")
+		return
+	}
+	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-previous-event", Value: true})
+}
+
 func createPreDeployJobChart(
 	ctx context.Context,
 	stackName string,

+ 1 - 3
api/server/handlers/porter_app/create_and_update_events.go

@@ -258,12 +258,10 @@ func (p *CreateUpdatePorterAppEventHandler) maybeUpdateDeployEvent(ctx context.C
 	telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "updating-deployment-event", Value: false})
 
 	// first check to see if the event is empty, meaning there was no match found
-	if matchEvent.Type != string(types.PorterAppEventType_Deploy) || matchEvent.Status != "PROGRESSING" {
+	if matchEvent.ID == uuid.Nil || matchEvent.Status != "PROGRESSING" {
 		return types.PorterAppEvent{}
 	}
 
-	fmt.Printf("found matching deploy event: %v\n", matchEvent)
-
 	serviceStatus, ok := matchEvent.Metadata["service_status"]
 	if !ok {
 		_ = telemetry.Error(ctx, span, nil, "service status not found in deploy event metadata")

+ 1 - 0
api/server/handlers/porter_app/rollback.go

@@ -31,6 +31,7 @@ func NewRollbackPorterAppHandler(
 	}
 }
 
+// TODO: make this just call create-porter-app
 func (c *RollbackPorterAppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	ctx, span := telemetry.NewSpan(r.Context(), "serve-rollback-porter-app")
 	defer span.End()

+ 6 - 18
dashboard/src/main/home/app-dashboard/expanded-app/ExpandedApp.tsx

@@ -69,7 +69,6 @@ const validTabs = [
   "environment",
   "build-settings",
   "settings",
-  "events",
   "helm-values",
 ] as const;
 const DEFAULT_TAB = "activity";
@@ -618,6 +617,12 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
   };
 
   const renderTabContents = () => {
+    if (eventId != null && eventId !== "") {
+      return <EventFocusView
+        eventId={eventId}
+        appData={appData}
+      />;
+    }
     switch (selectedTab) {
       case "activity":
         return <ActivityFeed
@@ -723,19 +728,6 @@ const ExpandedApp: React.FC<Props> = ({ ...props }) => {
             </Button>
           </>
         );
-      case "events":
-        if (eventId != null) {
-          return <EventFocusView
-            eventId={eventId}
-            appData={appData}
-          />;
-        } else {
-          return <ActivityFeed
-            chart={appData.chart}
-            stackName={appData?.app?.name}
-            appData={appData}
-          />;
-        }
       case "logs":
         return <LogSection currentChart={appData.chart} services={services} />;
       case "metrics":
@@ -1023,10 +1015,6 @@ const A = styled.a`
   align-items: center;
 `;
 
-const Underline = styled.div`
-  border-bottom: 1px solid #ffffff;
-`;
-
 const RefreshButton = styled.div`
   color: #ffffff;
   display: flex;

+ 1 - 1
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/cards/BuildEventCard.tsx

@@ -36,7 +36,7 @@ const BuildEventCard: React.FC<Props> = ({ event, appData }) => {
       case "FAILED":
         return <Text color="#FF6060">Build failed</Text>;
       default:
-        return <Text color="#aaaabb66">Build in progress...</Text>;
+        return <Text color="helper">Build in progress...</Text>;
     }
   };
 

+ 20 - 0
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/cards/DeployEventCard.tsx

@@ -60,6 +60,26 @@ const DeployEventCard: React.FC<Props> = ({ event, appData }) => {
             </Text>
           );
         }
+      case "CANCELED":
+        if (event.metadata.service_status != null) {
+          let canceledServices = 0;
+          for (const key in event.metadata.service_status) {
+            if (event.metadata.service_status[key] === "CANCELED") {
+              canceledServices++;
+            }
+          }
+          return (
+            <Text color="#FFBF00">
+              Canceled deploy of <Code>{event.metadata.image_tag}</Code> to {canceledServices} service{canceledServices === 1 ? "" : "s"}
+            </Text>
+          );
+        } else {
+          return (
+            <Text color="#FFBF00">
+              Deployment canceled
+            </Text>
+          );
+        }
       default:
         if (event.metadata.service_status != null) {
           return (

+ 2 - 0
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/utils.ts

@@ -44,6 +44,8 @@ export const getStatusIcon = (status: string) => {
             return failure;
         case "PROGRESSING":
             return loading;
+        case "CANCELED":
+            return failure;
         default:
             return loading;
     }