فهرست منبع

Merge pull request #1763 from porter-dev/belanger/blue-green-deployment-cli

Update blue-green deployment methods to include scale down buffer
abelanger5 4 سال پیش
والد
کامیت
9634e51493
2فایلهای تغییر یافته به همراه66 افزوده شده و 31 حذف شده
  1. 38 9
      cli/cmd/bluegreen.go
  2. 28 22
      cli/cmd/deploy/deploy.go

+ 38 - 9
cli/cmd/bluegreen.go

@@ -9,6 +9,7 @@ import (
 	"github.com/fatih/color"
 	api "github.com/porter-dev/porter/api/client"
 	"github.com/porter-dev/porter/api/types"
+	"github.com/porter-dev/porter/cli/cmd/deploy"
 	"github.com/spf13/cobra"
 	appsv1 "k8s.io/api/apps/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -72,9 +73,8 @@ func bluegreenSwitch(_ *types.GetAuthenticatedUserResponse, client *api.Client,
 		return fmt.Errorf("target application is not a web chart")
 	}
 
-	// TODO: check that bluegreen is enabled
+	currActiveImage := deploy.GetCurrActiveBlueGreenImage(webRelease.Config)
 
-	// get the replicasets attached to the deployment
 	sharedConf := &PorterRunSharedConfig{
 		Client: client,
 	}
@@ -91,6 +91,8 @@ func bluegreenSwitch(_ *types.GetAuthenticatedUserResponse, client *api.Client,
 
 	success := false
 
+	color.New(color.FgGreen).Printf("Waiting for the new version of the application %s to be ready\n", app)
+
 	for time.Now().Before(timeWait) {
 		// refresh the client every 10 minutes
 		if time.Now().After(prevRefresh.Add(10 * time.Minute)) {
@@ -136,13 +138,23 @@ func bluegreenSwitch(_ *types.GetAuthenticatedUserResponse, client *api.Client,
 						return err
 					}
 
-					err = deployAgent.UpdateImageAndValues(map[string]interface{}{
-						"bluegreen": map[string]interface{}{
-							"enabled":        true,
-							"activeImageTag": tag,
-							"imageTags":      []string{tag},
-						},
-					})
+					if currActiveImage == "" {
+						err = deployAgent.UpdateImageAndValues(map[string]interface{}{
+							"bluegreen": map[string]interface{}{
+								"enabled":        true,
+								"activeImageTag": tag,
+								"imageTags":      []string{tag},
+							},
+						})
+					} else {
+						err = deployAgent.UpdateImageAndValues(map[string]interface{}{
+							"bluegreen": map[string]interface{}{
+								"enabled":        true,
+								"activeImageTag": tag,
+								"imageTags":      []string{currActiveImage, tag},
+							},
+						})
+					}
 
 					if err != nil {
 						return err
@@ -169,6 +181,23 @@ func bluegreenSwitch(_ *types.GetAuthenticatedUserResponse, client *api.Client,
 		return fmt.Errorf("new application was not ready within 30 minutes")
 	}
 
+	// wait 30 seconds before removing old deployment
+	time.Sleep(30 * time.Second)
+
+	deployAgent, err := updateGetAgent(client)
+
+	if err != nil {
+		return err
+	}
+
+	err = deployAgent.UpdateImageAndValues(map[string]interface{}{
+		"bluegreen": map[string]interface{}{
+			"enabled":        true,
+			"activeImageTag": tag,
+			"imageTags":      []string{tag},
+		},
+	})
+
 	return nil
 }
 

+ 28 - 22
cli/cmd/deploy/deploy.go

@@ -341,28 +341,15 @@ func (d *DeployAgent) UpdateImageAndValues(overrideValues map[string]interface{}
 
 	mergedValues := utils.CoalesceValues(d.release.Config, overrideValues)
 
-	// if blue-green deployments are enabled, preserve the active tag value and append the new tag to the
-	// imageTags object
-	if bgInter, ok := mergedValues["bluegreen"]; ok {
-		if bgVal, ok := bgInter.(map[string]interface{}); ok {
-			if enabledInter, ok := bgVal["enabled"]; ok {
-				if enabledVal, ok := enabledInter.(bool); ok && enabledVal {
-					// they're enabled -- read the activeTagValue and construct the new bluegreen object
-					if activeTagInter, ok := bgVal["activeImageTag"]; ok {
-						if activeTagVal, ok := activeTagInter.(string); ok {
-							// only overwrite if the active tag value is not the same as the target tag. otherwise
-							// this has been modified already and inserted into overrideValues.
-							if activeTagVal != d.tag {
-								mergedValues["bluegreen"] = map[string]interface{}{
-									"enabled":        true,
-									"activeImageTag": activeTagVal,
-									"imageTags":      []string{activeTagVal, d.tag},
-								}
-							}
-						}
-					}
-				}
-			}
+	activeBlueGreenTagVal := GetCurrActiveBlueGreenImage(mergedValues)
+
+	// only overwrite if the active tag value is not the same as the target tag. otherwise
+	// this has been modified already and inserted into overrideValues.
+	if activeBlueGreenTagVal != "" && activeBlueGreenTagVal != d.tag {
+		mergedValues["bluegreen"] = map[string]interface{}{
+			"enabled":        true,
+			"activeImageTag": activeBlueGreenTagVal,
+			"imageTags":      []string{activeBlueGreenTagVal, d.tag},
 		}
 	}
 
@@ -702,3 +689,22 @@ func getNestedMap(obj map[string]interface{}, fields ...string) (map[string]inte
 
 	return res, nil
 }
+
+func GetCurrActiveBlueGreenImage(vals map[string]interface{}) string {
+	if bgInter, ok := vals["bluegreen"]; ok {
+		if bgVal, ok := bgInter.(map[string]interface{}); ok {
+			if enabledInter, ok := bgVal["enabled"]; ok {
+				if enabledVal, ok := enabledInter.(bool); ok && enabledVal {
+					// they're enabled -- read the activeTagValue and construct the new bluegreen object
+					if activeTagInter, ok := bgVal["activeImageTag"]; ok {
+						if activeTagVal, ok := activeTagInter.(string); ok {
+							return activeTagVal
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return ""
+}