Skip to content

Commit

Permalink
Merge branch 'v8' into canary-restart-command-v8
Browse files Browse the repository at this point in the history
  • Loading branch information
gururajsh committed Jul 31, 2024
2 parents bf63f85 + 6e0a003 commit 2b090dd
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 22 deletions.
2 changes: 1 addition & 1 deletion api/cloudcontroller/ccv3/constant/deployment_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ const (
// Rolling means a new web process will be created for the app and instances will roll from the old one to the new one.
DeploymentStrategyRolling DeploymentStrategy = "rolling"

// Canary means a new web process will be created for the app and one instance is updated to the new one.
// Canary means after a web process is created for the app the deployment will pause for evaluation until it is continued or canceled.
DeploymentStrategyCanary DeploymentStrategy = "canary"
)
32 changes: 31 additions & 1 deletion command/v7/shared/app_summary_displayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,24 @@ func (display AppSummaryDisplayer) displayProcessTable(summary v7action.Detailed

if summary.Deployment.StatusValue == constant.DeploymentStatusValueActive {
display.UI.DisplayNewline()
display.UI.DisplayText(fmt.Sprintf("%s deployment currently %s.",
display.UI.DisplayText(display.getDeploymentStatusText(summary))
if summary.Deployment.Strategy == constant.DeploymentStrategyCanary && summary.Deployment.StatusReason == constant.DeploymentStatusReasonPaused {
display.UI.DisplayNewline()
display.UI.DisplayText(fmt.Sprintf("Please run `cf continue-deployment %s` to promote the canary deployment, or `cf cancel-deployment %s` to rollback to the previous version.", summary.Application.Name, summary.Application.Name))
}
}
}

func (display AppSummaryDisplayer) getDeploymentStatusText(summary v7action.DetailedApplicationSummary) string {
var lastStatusChangeTime = display.getLastStatusChangeTime(summary)

if lastStatusChangeTime != "" {
return fmt.Sprintf("%s deployment currently %s (since %s)",
cases.Title(language.English, cases.NoLower).String(string(summary.Deployment.Strategy)),
summary.Deployment.StatusReason,
lastStatusChangeTime)
} else {
return fmt.Sprintf("%s deployment currently %s",
cases.Title(language.English, cases.NoLower).String(string(summary.Deployment.Strategy)),
summary.Deployment.StatusReason))

Check failure on line 186 in command/v7/shared/app_summary_displayer.go

View workflow job for this annotation

GitHub Actions / lint

syntax error: unexpected ) at end of statement (typecheck)

Check failure on line 186 in command/v7/shared/app_summary_displayer.go

View workflow job for this annotation

GitHub Actions / lint

expected statement, found ')' (typecheck)

Check failure on line 186 in command/v7/shared/app_summary_displayer.go

View workflow job for this annotation

GitHub Actions / lint

syntax error: unexpected ) at end of statement) (typecheck)

Check failure on line 186 in command/v7/shared/app_summary_displayer.go

View workflow job for this annotation

GitHub Actions / lint

syntax error: unexpected ) at end of statement) (typecheck)

Expand All @@ -188,6 +205,19 @@ func (display AppSummaryDisplayer) getCreatedTime(summary v7action.DetailedAppli
return ""
}

func (display AppSummaryDisplayer) getLastStatusChangeTime(summary v7action.DetailedApplicationSummary) string {
if summary.Deployment.LastStatusChange != "" {
timestamp, err := time.Parse(time.RFC3339, summary.Deployment.LastStatusChange)
if err != nil {
log.WithField("last_status_change", summary.Deployment.LastStatusChange).Errorln("error parsing last status change:", err)
}

return display.UI.UserFriendlyDate(timestamp)
}

return ""
}

func (AppSummaryDisplayer) appInstanceDate(input time.Time) string {
return input.UTC().Format(time.RFC3339)
}
Expand Down
100 changes: 91 additions & 9 deletions command/v7/shared/app_summary_displayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,34 +659,116 @@ var _ = Describe("app summary displayer", func() {
When("there is an active deployment", func() {
When("the deployment strategy is rolling", func() {
When("the deployment is in progress", func() {
When("last status change has a timestamp", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyRolling,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
LastStatusChange: "2024-07-29T17:32:29Z",
},
}
})

It("displays the message", func() {
Expect(testUI.Out).To(Say(`Rolling deployment currently DEPLOYING \(since Mon 29 Jul 13:32:29 EDT 2024\)`))
})
})

When("last status change is an empty string", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyRolling,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
LastStatusChange: "",
},
}
})

It("displays the message", func() {
Expect(testUI.Out).To(Say(`Rolling deployment currently DEPLOYING\n`))
Expect(testUI.Out).NotTo(Say(`\(since`))
})
})
})

When("the deployment is cancelled", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyRolling,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
Strategy: constant.DeploymentStrategyRolling,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonCanceling,
LastStatusChange: "2024-07-29T17:32:29Z",
},
}
})

It("displays the message", func() {
Expect(testUI.Out).To(Say("Rolling deployment currently DEPLOYING."))
Expect(testUI.Out).To(Say(`Rolling deployment currently CANCELING \(since Mon 29 Jul 13:32:29 EDT 2024\)`))
})
})
})
When("the deployment strategy is canary", func() {
When("the deployment is in progress", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonDeploying,
LastStatusChange: "2024-07-29T17:32:29Z",
},
}
})

When("the deployment is cancelled", func() {
It("displays the message", func() {
Expect(testUI.Out).To(Say(`Canary deployment currently DEPLOYING \(since Mon 29 Jul 13:32:29 EDT 2024\)`))
Expect(testUI.Out).NotTo(Say(`promote the canary deployment`))
})
})

When("the deployment is paused", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
ApplicationSummary: v7action.ApplicationSummary{
Application: resources.Application{
Name: "foobar",
},
},
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyRolling,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonCanceling,
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonPaused,
LastStatusChange: "2024-07-29T17:32:29Z",
},
}
})

It("displays the message", func() {
Expect(testUI.Out).To(Say(`Canary deployment currently PAUSED \(since Mon 29 Jul 13:32:29 EDT 2024\)`))
Expect(testUI.Out).To(Say("Please run `cf continue-deployment foobar` to promote the canary deployment, or `cf cancel-deployment foobar` to rollback to the previous version."))
})
})

When("the deployment is canceling", func() {
BeforeEach(func() {
summary = v7action.DetailedApplicationSummary{
Deployment: resources.Deployment{
Strategy: constant.DeploymentStrategyCanary,
StatusValue: constant.DeploymentStatusValueActive,
StatusReason: constant.DeploymentStatusReasonCanceling,
LastStatusChange: "2024-07-29T17:32:29Z",
},
}
})

It("displays the message", func() {
Expect(testUI.Out).To(Say("Rolling deployment currently CANCELING."))
Expect(testUI.Out).To(Say(`Canary deployment currently CANCELING \(since Mon 29 Jul 13:32:29 EDT 2024\)`))
Expect(testUI.Out).NotTo(Say(`promote the canary deployment`))
})
})
})
Expand Down
27 changes: 16 additions & 11 deletions resources/deployment_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
)

type Deployment struct {
GUID string
State constant.DeploymentState
StatusValue constant.DeploymentStatusValue
StatusReason constant.DeploymentStatusReason
RevisionGUID string
DropletGUID string
CreatedAt string
UpdatedAt string
Relationships Relationships
NewProcesses []Process
Strategy constant.DeploymentStrategy
GUID string
State constant.DeploymentState
StatusValue constant.DeploymentStatusValue
StatusReason constant.DeploymentStatusReason
LastStatusChange string
RevisionGUID string
DropletGUID string
CreatedAt string
UpdatedAt string
Relationships Relationships
NewProcesses []Process
Strategy constant.DeploymentStrategy
}

// MarshalJSON converts a Deployment into a Cloud Controller Deployment.
Expand Down Expand Up @@ -62,6 +63,9 @@ func (d *Deployment) UnmarshalJSON(data []byte) error {
Relationships Relationships `json:"relationships,omitempty"`
State constant.DeploymentState `json:"state,omitempty"`
Status struct {
Details struct {
LastStatusChange string `json:"last_status_change"`
}
Value constant.DeploymentStatusValue `json:"value"`
Reason constant.DeploymentStatusReason `json:"reason"`
} `json:"status"`
Expand All @@ -81,6 +85,7 @@ func (d *Deployment) UnmarshalJSON(data []byte) error {
d.State = ccDeployment.State
d.StatusValue = ccDeployment.Status.Value
d.StatusReason = ccDeployment.Status.Reason
d.LastStatusChange = ccDeployment.Status.Details.LastStatusChange
d.DropletGUID = ccDeployment.Droplet.GUID
d.NewProcesses = ccDeployment.NewProcesses
d.Strategy = ccDeployment.Strategy
Expand Down

0 comments on commit 2b090dd

Please sign in to comment.