Skip to content

Commit

Permalink
Display current step in the canary deployment
Browse files Browse the repository at this point in the history
Signed-off-by: João Pereira <joao.pereira@broadcom.com>
  • Loading branch information
joaopapereira committed Feb 12, 2025
1 parent 610d4c4 commit 19498d1
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 28 deletions.
2 changes: 1 addition & 1 deletion actor/v7action/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (actor Actor) GetLatestActiveDeploymentForApp(appGUID string) (resources.De
return resources.Deployment{}, Warnings(warnings), actionerror.ActiveDeploymentNotFoundError{}
}

return resources.Deployment(ccDeployments[0]), Warnings(warnings), nil
return ccDeployments[0], Warnings(warnings), nil
}

func (actor Actor) CancelDeployment(deploymentGUID string) (Warnings, error) {
Expand Down
1 change: 0 additions & 1 deletion api/cloudcontroller/ccv3/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ var _ = Describe("Application", func() {
})

When("lifecycle type buildpack is provided", func() {

When("other buildpacks are provided", func() {
BeforeEach(func() {
appBytes = []byte(`{"lifecycle":{"data":{"buildpacks":["some-buildpack"]},"type":"buildpack"}}`)
Expand Down
10 changes: 9 additions & 1 deletion api/cloudcontroller/ccv3/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,13 @@ var _ = Describe("Deployment", func() {
"strategy": "canary",
"status": {
"value": "FINALIZED",
"reason": "SUPERSEDED"
"reason": "SUPERSEDED",
"canary": {
"steps": {
"current": 4,
"total": 5
}
}
},
"droplet": {
"guid": "some-droplet-guid"
Expand Down Expand Up @@ -374,6 +380,8 @@ var _ = Describe("Deployment", func() {
Expect(deployment.StatusValue).To(Equal(constant.DeploymentStatusValueFinalized))
Expect(deployment.StatusReason).To(Equal(constant.DeploymentStatusReasonSuperseded))
Expect(deployment.Strategy).To(Equal(constant.DeploymentStrategyCanary))
Expect(deployment.CanaryStatus.Steps.CurrentStep).To(Equal(4))
Expect(deployment.CanaryStatus.Steps.TotalSteps).To(Equal(5))
})
})

Expand Down
7 changes: 7 additions & 0 deletions command/v7/shared/app_summary_displayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,17 @@ func (display AppSummaryDisplayer) displayProcessTable(summary v7action.Detailed
if maxInFlight > 0 {
maxInFlightRow = append(maxInFlightRow, display.UI.TranslateText("max-in-flight:"), strconv.Itoa(maxInFlight))
}
var canaryStepsRow []string
if summary.Deployment.CanaryStatus.Steps.TotalSteps > 0 {
stepStatus := summary.Deployment.CanaryStatus.Steps
canaryStepsRow = []string{display.UI.TranslateText("canary-steps:"), fmt.Sprintf("%d/%d", stepStatus.CurrentStep, stepStatus.TotalSteps)}

}

keyValueTable := [][]string{
{display.UI.TranslateText("strategy:"), strings.ToLower(string(summary.Deployment.Strategy))},
maxInFlightRow,
canaryStepsRow,
}

display.UI.DisplayKeyValueTable("", keyValueTable, ui.DefaultTableSpacePadding)
Expand Down
64 changes: 49 additions & 15 deletions command/v7/shared/app_summary_displayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -887,9 +887,15 @@ var _ = Describe("app summary displayer", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
CanaryStatus: resources.CanaryStatus{
Steps: resources.CanaryStepStatus{
CurrentStep: 2,
TotalSteps: 5,
},
},
LastStatusChange: LastStatusChangeTimeString,
Options: resources.DeploymentOpts{
MaxInFlight: 2,
Expand All @@ -907,15 +913,25 @@ var _ = Describe("app summary displayer", func() {
It("displays max-in-flight value", func() {
Expect(testUI.Out).To(Say(`max-in-flight: 2`))
})

It("displays the step the deployment is currently in", func() {
Expect(testUI.Out).To(Say(`canary-steps: 2/5`))
})
})

When("max-in-flight value is default", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
CanaryStatus: resources.CanaryStatus{
Steps: resources.CanaryStepStatus{
CurrentStep: 2,
TotalSteps: 5,
},
},
LastStatusChange: LastStatusChangeTimeString,
Options: resources.DeploymentOpts{
MaxInFlight: maxInFlightDefaultValue,
Expand Down Expand Up @@ -943,9 +959,15 @@ var _ = Describe("app summary displayer", func() {
},
},
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonPaused,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonPaused,
CanaryStatus: resources.CanaryStatus{
Steps: resources.CanaryStepStatus{
CurrentStep: 2,
TotalSteps: 5,
},
},
LastStatusChange: LastStatusChangeTimeString,
Options: resources.DeploymentOpts{
MaxInFlight: 2,
Expand Down Expand Up @@ -974,9 +996,15 @@ var _ = Describe("app summary displayer", func() {
},
},
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonPaused,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonPaused,
CanaryStatus: resources.CanaryStatus{
Steps: resources.CanaryStepStatus{
CurrentStep: 2,
TotalSteps: 5,
},
},
LastStatusChange: LastStatusChangeTimeString,
Options: resources.DeploymentOpts{
MaxInFlight: maxInFlightDefaultValue,
Expand All @@ -999,9 +1027,15 @@ var _ = Describe("app summary displayer", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonCanceling,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonCanceling,
CanaryStatus: resources.CanaryStatus{
Steps: resources.CanaryStepStatus{
CurrentStep: 2,
TotalSteps: 5,
},
},
LastStatusChange: LastStatusChangeTimeString,
Options: resources.DeploymentOpts{
MaxInFlight: 2,
Expand Down
1 change: 1 addition & 0 deletions integration/v7/isolated/app_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ applications:
session1 := helpers.CF("app", appName)
Eventually(session1).Should(Say("Active deployment with status PAUSED"))
Eventually(session1).Should(Say("strategy: canary"))
Expect(session1).To(Say("canary-steps: 0/1"))
Eventually(session1).Should(Exit(0))
})
})
Expand Down
28 changes: 21 additions & 7 deletions integration/v7/isolated/continue_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,29 @@ var _ = Describe("Continue Deployment", func() {

Context("when the continue is successful", func() {
When("There is a canary deployment", func() {
It("succeeds", func() {
helpers.WithHelloWorldApp(func(appDir string) {
helpers.CF("push", appName, "-p", appDir, "--strategy=canary").Wait()
When("instance steps are provided", func() {
It("displays the number of steps", func() {
helpers.WithHelloWorldApp(func(appDir string) {
helpers.CF("push", appName, "-p", appDir, "--strategy=canary", "--instance-steps 10,20,30,70", "-i 5").Wait()
})

session := helpers.CF("continue-deployment", appName)
Eventually(session).Should(Say("canary-steps: 1/4"))
Eventually(session).Should(Exit(0))
})
})

When("instance steps are NOT provided", func() {
It("succeeds", func() {
helpers.WithHelloWorldApp(func(appDir string) {
helpers.CF("push", appName, "-p", appDir, "--strategy=canary").Wait()
})

session := helpers.CF("continue-deployment", appName)
Eventually(session).Should(Say(fmt.Sprintf("Continuing deployment for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
Eventually(session).Should(Say(fmt.Sprintf(`TIP: Run 'cf app %s' to view app status.`, appName)))
Eventually(session).Should(Exit(0))
session := helpers.CF("continue-deployment", appName)
Eventually(session).Should(Say(fmt.Sprintf("Continuing deployment for app %s in org %s / space %s as %s...", appName, orgName, spaceName, userName)))
Eventually(session).Should(Say(fmt.Sprintf(`TIP: Run 'cf app %s' to view app status.`, appName)))
Eventually(session).Should(Exit(0))
})
})
})
})
Expand Down
4 changes: 3 additions & 1 deletion integration/v7/push/canary_push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ var _ = Describe("push with --strategy canary", func() {
It("pushes the app and creates a new deployment and notes the max-in-flight value", func() {
helpers.WithHelloWorldApp(func(appDir string) {
session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir},
PushCommandName, appName, "--strategy", "canary",
PushCommandName, appName, "--strategy", "canary", "--instance-steps=10,60",
)

Eventually(session).Should(Exit(0))
Expand All @@ -55,6 +55,7 @@ var _ = Describe("push with --strategy canary", func() {
Expect(session).To(Say("Active deployment with status PAUSED"))
Expect(session).To(Say("strategy: canary"))
Expect(session).To(Say("max-in-flight: 1"))
Expect(session).To(Say("canary-steps: 1/2"))
Expect(session).To(Say("Please run `cf continue-deployment %s` to promote the canary deployment, or `cf cancel-deployment %s` to rollback to the previous version.", appName, appName))
Expect(session).To(Exit(0))
})
Expand Down Expand Up @@ -86,6 +87,7 @@ var _ = Describe("push with --strategy canary", func() {
Expect(session).To(Say("Active deployment with status PAUSED"))
Expect(session).To(Say("strategy: canary"))
Expect(session).To(Say("max-in-flight: 2"))
Expect(session).To(Say("canary-steps: 0/1"))
Expect(session).To(Say("Please run `cf continue-deployment %s` to promote the canary deployment, or `cf cancel-deployment %s` to rollback to the previous version.", appName, appName))
Expect(session).To(Exit(0))
})
Expand Down
16 changes: 14 additions & 2 deletions resources/deployment_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Deployment struct {
State constant.DeploymentState
StatusValue constant.DeploymentStatusValue
StatusReason constant.DeploymentStatusReason
CanaryStatus CanaryStatus
LastStatusChange string
Options DeploymentOpts
RevisionGUID string
Expand Down Expand Up @@ -78,6 +79,15 @@ func (d Deployment) MarshalJSON() ([]byte, error) {
return json.Marshal(ccDeployment)
}

type CanaryStepStatus struct {
CurrentStep int `json:"current"`
TotalSteps int `json:"total"`
}

type CanaryStatus struct {
Steps CanaryStepStatus `json:"steps"`
}

// UnmarshalJSON helps unmarshal a Cloud Controller Deployment response.
func (d *Deployment) UnmarshalJSON(data []byte) error {
var ccDeployment struct {
Expand All @@ -89,8 +99,9 @@ func (d *Deployment) UnmarshalJSON(data []byte) error {
Details struct {
LastStatusChange string `json:"last_status_change"`
}
Value constant.DeploymentStatusValue `json:"value"`
Reason constant.DeploymentStatusReason `json:"reason"`
Value constant.DeploymentStatusValue `json:"value"`
Reason constant.DeploymentStatusReason `json:"reason"`
CanaryStatus CanaryStatus `json:"canary,omitempty"`
} `json:"status"`
Droplet Droplet `json:"droplet,omitempty"`
NewProcesses []Process `json:"new_processes,omitempty"`
Expand All @@ -109,6 +120,7 @@ func (d *Deployment) UnmarshalJSON(data []byte) error {
d.State = ccDeployment.State
d.StatusValue = ccDeployment.Status.Value
d.StatusReason = ccDeployment.Status.Reason
d.CanaryStatus = ccDeployment.Status.CanaryStatus
d.LastStatusChange = ccDeployment.Status.Details.LastStatusChange
d.DropletGUID = ccDeployment.Droplet.GUID
d.NewProcesses = ccDeployment.NewProcesses
Expand Down

0 comments on commit 19498d1

Please sign in to comment.