2
0
Эх сурвалжийг харах

Toggle auto-rollback enabled (#4231)

Feroze Mohideen 2 жил өмнө
parent
commit
83bba70328

+ 37 - 5
dashboard/src/main/home/app-dashboard/app-view/tabs/Settings.tsx

@@ -146,14 +146,46 @@ const Settings: React.FC = () => {
 
   return (
     <StyledSettingsTab>
+      <Text size={16}>Enable application auto-rollback</Text>
+      <Spacer y={0.5} />
+      <Text color="helper">
+        If enabled, Porter will automatically trigger a rollback to the last
+        successful deployment if any services of the new deployment fail to
+        deploy.
+      </Text>
+      <Spacer y={0.5} />
+      <Controller
+        name={`app.autoRollback`}
+        control={control}
+        render={({ field: { value, onChange } }) => (
+          <Checkbox
+            checked={value.enabled}
+            toggleChecked={() => {
+              onChange({
+                ...value,
+                enabled: !value.enabled,
+              });
+            }}
+            disabled={value.readOnly}
+            disabledTooltip={
+              "You may only edit this field in your porter.yaml."
+            }
+          >
+            <Text color="helper">Auto-rollback enabled</Text>
+          </Checkbox>
+        )}
+      />
+      <Spacer y={1} />
       {currentCluster?.cloud_provider === "AWS" &&
         currentProject?.efs_enabled && (
           <>
-            <Text size={16}>
-              Enable shared storage across services for &quot;{porterApp.name}
-              &quot;
-            </Text>
+            <Text size={16}>Enable shared storage (EFS)</Text>
             <Spacer y={0.5} />
+            <Text color="helper">
+              If enabled, Porter will mount a shared storage drive in your
+              cluster, accessible by all services of this app. This drive is
+              accessible at /data/efs/{porterApp.name}
+            </Text>
             <Spacer y={0.5} />
             <Controller
               name={`app.efsStorage`}
@@ -172,7 +204,7 @@ const Settings: React.FC = () => {
                     "You may only edit this field in your porter.yaml."
                   }
                 >
-                  <Text color="helper">Enable EFS Storage</Text>
+                  <Text color="helper">EFS Storage enabled</Text>
                 </Checkbox>
               )}
             />

+ 0 - 141
internal/porter_app/test/parse_test.go

@@ -47,82 +47,6 @@ func TestParseYAML(t *testing.T) {
 
 var result_nobuild = &porterv1.PorterApp{
 	Name: "test-app",
-	Services: map[string]*porterv1.Service{
-		"example-web": {
-			Name:         "example-web",
-			RunOptional:  pointer.String("node index.js"),
-			Port:         8080,
-			CpuCores:     0.1,
-			RamMegabytes: 256,
-			Gpu: &porterv1.GPU{
-				Enabled:        false,
-				GpuCoresNvidia: 0,
-			},
-			Config: &porterv1.Service_WebConfig{
-				WebConfig: &porterv1.WebServiceConfig{
-					Autoscaling: &porterv1.Autoscaling{
-						Enabled:                true,
-						MinInstances:           1,
-						MaxInstances:           3,
-						CpuThresholdPercent:    60,
-						MemoryThresholdPercent: 60,
-					},
-					Domains: []*porterv1.Domain{
-						{
-							Name: "test1.example.com",
-						},
-						{
-							Name: "test2.example.com",
-						},
-					},
-					HealthCheck: &porterv1.HealthCheck{
-						Enabled:  true,
-						HttpPath: "/healthz",
-					},
-				},
-			},
-			Type: 1,
-		},
-		"example-wkr": {
-			Name:              "example-wkr",
-			RunOptional:       pointer.String("echo 'work'"),
-			InstancesOptional: pointer.Int32(1),
-			Port:              80,
-			CpuCores:          0.1,
-			RamMegabytes:      256,
-			GpuCoresNvidia:    0,
-			Gpu: &porterv1.GPU{
-				Enabled:        false,
-				GpuCoresNvidia: 0,
-			},
-			Config: &porterv1.Service_WorkerConfig{
-				WorkerConfig: &porterv1.WorkerServiceConfig{
-					Autoscaling: nil,
-				},
-			},
-			Type: 2,
-		},
-		"example-job": {
-			Name:           "example-job",
-			RunOptional:    pointer.String("echo 'hello world'"),
-			CpuCores:       0.1,
-			RamMegabytes:   256,
-			GpuCoresNvidia: 0,
-			Gpu: &porterv1.GPU{
-				Enabled:        false,
-				GpuCoresNvidia: 0,
-			},
-			Config: &porterv1.Service_JobConfig{
-				JobConfig: &porterv1.JobServiceConfig{
-					AllowConcurrentOptional: pointer.Bool(true),
-					Cron:                    "*/10 * * * *",
-					SuspendCron:             pointer.Bool(false),
-					TimeoutSeconds:          60,
-				},
-			},
-			Type: 3,
-		},
-	},
 	ServiceList: []*porterv1.Service{
 		{
 			Name:           "example-web",
@@ -227,71 +151,6 @@ var (
 
 var v1_result_nobuild_no_image = &porterv1.PorterApp{
 	Name: "test-app",
-	Services: map[string]*porterv1.Service{
-		"example-job": {
-			Name:           "example-job",
-			RunOptional:    pointer.String("echo 'hello world'"),
-			CpuCores:       0.1,
-			RamMegabytes:   256,
-			GpuCoresNvidia: 0,
-			Config: &porterv1.Service_JobConfig{
-				JobConfig: &porterv1.JobServiceConfig{
-					AllowConcurrentOptional: &trueBool,
-					Cron:                    "*/10 * * * *",
-				},
-			},
-			Type: 3,
-		},
-		"example-wkr": {
-			Name:              "example-wkr",
-			RunOptional:       pointer.String("echo 'work'"),
-			InstancesOptional: &oneInt32,
-			Port:              80,
-			CpuCores:          0.1,
-			RamMegabytes:      256,
-			GpuCoresNvidia:    0,
-			Config: &porterv1.Service_WorkerConfig{
-				WorkerConfig: &porterv1.WorkerServiceConfig{
-					Autoscaling: nil,
-				},
-			},
-			Type: 2,
-		},
-		"example-web": {
-			Name:              "example-web",
-			RunOptional:       pointer.String("node index.js"),
-			InstancesOptional: &zeroInt32,
-			Port:              8080,
-			CpuCores:          0.1,
-			GpuCoresNvidia:    0,
-			RamMegabytes:      256,
-			Config: &porterv1.Service_WebConfig{
-				WebConfig: &porterv1.WebServiceConfig{
-					Autoscaling: &porterv1.Autoscaling{
-						Enabled:                true,
-						MinInstances:           1,
-						MaxInstances:           3,
-						CpuThresholdPercent:    60,
-						MemoryThresholdPercent: 60,
-					},
-					Domains: []*porterv1.Domain{
-						{
-							Name: "test1.example.com",
-						},
-						{
-							Name: "test2.example.com",
-						},
-					},
-					HealthCheck: &porterv1.HealthCheck{
-						Enabled:  true,
-						HttpPath: "/healthz",
-					},
-					Private: pointer.Bool(false),
-				},
-			},
-			Type: 1,
-		},
-	},
 	ServiceList: []*porterv1.Service{
 		{
 			Name:              "example-web",

+ 1 - 8
internal/porter_app/v1/yaml.go

@@ -71,8 +71,6 @@ func AppProtoFromYaml(ctx context.Context, porterYamlBytes []byte) (*porterv1.Po
 		return nil, nil, telemetry.Error(ctx, span, nil, "porter yaml is missing services")
 	}
 
-	// service map is only needed for backwards compatibility at this time
-	serviceMap := make(map[string]*porterv1.Service)
 	var serviceList []*porterv1.Service
 
 	for name, service := range services {
@@ -85,11 +83,7 @@ func AppProtoFromYaml(ctx context.Context, porterYamlBytes []byte) (*porterv1.Po
 		}
 		serviceProto.Name = name
 
-		serviceMap[name] = serviceProto
-	}
-
-	for _, service := range serviceMap {
-		serviceList = append(serviceList, service)
+		serviceList = append(serviceList, serviceProto)
 	}
 
 	sort.Slice(serviceList, func(i, j int) bool {
@@ -100,7 +94,6 @@ func AppProtoFromYaml(ctx context.Context, porterYamlBytes []byte) (*porterv1.Po
 	})
 
 	appProto.ServiceList = serviceList
-	appProto.Services = serviceMap // nolint:staticcheck // temporarily using deprecated field for backwards compatibility
 
 	if porterYaml.Release != nil {
 		predeployProto, err := serviceProtoFromConfig(*porterYaml.Release, porterv1.ServiceType_SERVICE_TYPE_JOB)

+ 18 - 4
internal/porter_app/v2/yaml.go

@@ -109,6 +109,7 @@ type PorterApp struct {
 	EnvGroups    []string      `yaml:"envGroups,omitempty"`
 	EfsStorage   *EfsStorage   `yaml:"efsStorage,omitempty"`
 	RequiredApps []RequiredApp `yaml:"requiredApps,omitempty"`
+	AutoRollback *AutoRollback `yaml:"autoRollback,omitempty"`
 }
 
 // PorterAppWithAddons is the definition of a porter app in a Porter YAML file with addons
@@ -144,6 +145,11 @@ type EfsStorage struct {
 	Enabled bool `yaml:"enabled"`
 }
 
+// AutoRollback represents the auto rollback settings for a Porter app
+type AutoRollback struct {
+	Enabled bool `yaml:"enabled"`
+}
+
 // Build represents the build settings for a Porter app
 type Build struct {
 	Context    string   `yaml:"context,omitempty" validate:"dir"`
@@ -238,8 +244,6 @@ func ProtoFromApp(ctx context.Context, porterApp PorterApp) (*porterv1.PorterApp
 		}
 	}
 
-	// service map is only needed for backwards compatibility at this time
-	serviceMap := make(map[string]*porterv1.Service)
 	var services []*porterv1.Service
 
 	for _, service := range porterApp.Services {
@@ -254,10 +258,8 @@ func ProtoFromApp(ctx context.Context, porterApp PorterApp) (*porterv1.PorterApp
 		}
 
 		services = append(services, serviceProto)
-		serviceMap[service.Name] = serviceProto
 	}
 	appProto.ServiceList = services
-	appProto.Services = serviceMap // nolint:staticcheck // temporarily using deprecated field for backwards compatibility
 
 	if porterApp.Predeploy != nil {
 		predeployProto, err := serviceProtoFromConfig(*porterApp.Predeploy, porterv1.ServiceType_SERVICE_TYPE_JOB)
@@ -280,6 +282,12 @@ func ProtoFromApp(ctx context.Context, porterApp PorterApp) (*porterv1.PorterApp
 		}
 	}
 
+	if porterApp.AutoRollback != nil {
+		appProto.AutoRollback = &porterv1.AutoRollback{
+			Enabled: porterApp.AutoRollback.Enabled,
+		}
+	}
+
 	for _, requiredApp := range porterApp.RequiredApps {
 		var targetIdentifier *porterv1.DeploymentTargetIdentifier
 
@@ -527,6 +535,12 @@ func AppFromProto(appProto *porterv1.PorterApp) (PorterApp, error) {
 		}
 	}
 
+	if appProto.AutoRollback != nil {
+		porterApp.AutoRollback = &AutoRollback{
+			Enabled: appProto.AutoRollback.Enabled,
+		}
+	}
+
 	return porterApp, nil
 }