Export resource change counts from engine (#823)
This PR exports the aggregate resource changes for update and destroy operations. We'll use this information in #636 when summarizing previous updates. I initially started with a new struct that had fields like `Created`, `Deleted`, `Unchanged`, etc. But it became cumbersome with the seven different type of resource operations we perform. So instead went with the more flexible `map[deploy.StepOp]int`.
This commit is contained in:
commit
6f6fca7592
|
@ -139,7 +139,7 @@ func (b *localBackend) Update(stackName tokens.QName, pkg *pack.Package, root st
|
|||
|
||||
go displayEvents(events, done, debug)
|
||||
|
||||
if err = engine.Deploy(update, events, opts); err != nil {
|
||||
if _, err = engine.Deploy(update, events, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ func (b *localBackend) Destroy(stackName tokens.QName, pkg *pack.Package, root s
|
|||
|
||||
go displayEvents(events, done, debug)
|
||||
|
||||
if err := engine.Destroy(update, events, opts); err != nil {
|
||||
if _, err := engine.Destroy(update, events, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,10 @@ type UpdateOptions struct {
|
|||
Summary bool // true if we should only summarize resources and operations.
|
||||
}
|
||||
|
||||
func Deploy(update Update, events chan<- Event, opts UpdateOptions) error {
|
||||
// ResourceChanges contains the aggregate resource changes by operation type.
|
||||
type ResourceChanges map[deploy.StepOp]int
|
||||
|
||||
func Deploy(update Update, events chan<- Event, opts UpdateOptions) (ResourceChanges, error) {
|
||||
contract.Require(update != nil, "update")
|
||||
contract.Require(events != nil, "events")
|
||||
|
||||
|
@ -37,7 +40,7 @@ func Deploy(update Update, events chan<- Event, opts UpdateOptions) error {
|
|||
|
||||
info, err := planContextFromUpdate(update)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer info.Close()
|
||||
|
||||
|
@ -66,25 +69,27 @@ type deployOptions struct {
|
|||
Diag diag.Sink // the sink to use for diag'ing.
|
||||
}
|
||||
|
||||
func deployLatest(info *planContext, opts deployOptions) error {
|
||||
func deployLatest(info *planContext, opts deployOptions) (ResourceChanges, error) {
|
||||
result, err := plan(info, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var resourceChanges ResourceChanges
|
||||
if result != nil {
|
||||
defer contract.IgnoreClose(result)
|
||||
|
||||
// Make the current working directory the same as the program's, and restore it upon exit.
|
||||
done, err := result.Chdir()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer done()
|
||||
|
||||
if opts.DryRun {
|
||||
// If a dry run, just print the plan, don't actually carry out the deployment.
|
||||
// If a dry run, just print the plan, don't actually carry out the deployment. (Reporting 0 changes.)
|
||||
if err := printPlan(result); err != nil {
|
||||
return err
|
||||
return resourceChanges, err
|
||||
}
|
||||
} else {
|
||||
// Otherwise, we will actually deploy the latest bits.
|
||||
|
@ -99,7 +104,7 @@ func deployLatest(info *planContext, opts deployOptions) error {
|
|||
summary, _, _, err := result.Walk(actions, false)
|
||||
if err != nil && summary == nil {
|
||||
// Something went wrong, and no changes were made.
|
||||
return err
|
||||
return resourceChanges, err
|
||||
}
|
||||
contract.Assert(summary != nil)
|
||||
|
||||
|
@ -107,7 +112,8 @@ func deployLatest(info *planContext, opts deployOptions) error {
|
|||
var footer bytes.Buffer
|
||||
|
||||
// Print out the total number of steps performed (and their kinds), the duration, and any summary info.
|
||||
if c := printChangeSummary(&footer, actions.Ops, false); c != 0 {
|
||||
resourceChanges = ResourceChanges(actions.Ops)
|
||||
if c := printChangeSummary(&footer, resourceChanges, false); c != 0 {
|
||||
footer.WriteString(fmt.Sprintf("%vUpdate duration: %v%v\n",
|
||||
colors.SpecUnimportant, time.Since(start), colors.Reset))
|
||||
}
|
||||
|
@ -121,15 +127,16 @@ func deployLatest(info *planContext, opts deployOptions) error {
|
|||
opts.Events <- stdOutEventWithColor(&footer, opts.Color)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
return resourceChanges, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !opts.Diag.Success() {
|
||||
// If any error that wasn't printed above, be sure to make it evident in the output.
|
||||
return goerr.New("One or more errors occurred during this update")
|
||||
return resourceChanges, goerr.New("One or more errors occurred during this update")
|
||||
}
|
||||
return nil
|
||||
return resourceChanges, nil
|
||||
}
|
||||
|
||||
// deployActions pretty-prints the plan application process as it goes.
|
||||
|
|
|
@ -7,14 +7,14 @@ import (
|
|||
"github.com/pulumi/pulumi/pkg/util/contract"
|
||||
)
|
||||
|
||||
func Destroy(update Update, events chan<- Event, opts UpdateOptions) error {
|
||||
func Destroy(update Update, events chan<- Event, opts UpdateOptions) (ResourceChanges, error) {
|
||||
contract.Require(update != nil, "update")
|
||||
|
||||
defer func() { events <- cancelEvent() }()
|
||||
|
||||
info, err := planContextFromUpdate(update)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer info.Close()
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ func (res *planResult) Close() error {
|
|||
return res.Ctx.Close()
|
||||
}
|
||||
|
||||
// printPlan prints the plan's result to the plan's Options.Events stream.
|
||||
func printPlan(result *planResult) error {
|
||||
// First print config/unchanged/etc. if necessary.
|
||||
var prelude bytes.Buffer
|
||||
|
@ -180,7 +181,7 @@ func printPlan(result *planResult) error {
|
|||
|
||||
// Print a summary of operation counts.
|
||||
var summary bytes.Buffer
|
||||
printChangeSummary(&summary, actions.Ops, true)
|
||||
printChangeSummary(&summary, ResourceChanges(actions.Ops), true)
|
||||
result.Options.Events <- stdOutEventWithColor(&summary, result.Options.Color)
|
||||
return nil
|
||||
}
|
||||
|
@ -233,14 +234,15 @@ func printConfig(b *bytes.Buffer, cfg config.Map) {
|
|||
}
|
||||
}
|
||||
|
||||
func printChangeSummary(b *bytes.Buffer, counts map[deploy.StepOp]int, preview bool) int {
|
||||
changes := 0
|
||||
for op, c := range counts {
|
||||
// printChangeSummary writes summary informatiom about the resoures changed to the provided buffer.
|
||||
// Returns the total number of resources changed regardless of operation type.
|
||||
func printChangeSummary(b *bytes.Buffer, changes ResourceChanges, preview bool) int {
|
||||
changeCount := 0
|
||||
for op, c := range changes {
|
||||
if op != deploy.OpSame {
|
||||
changes += c
|
||||
changeCount += c
|
||||
}
|
||||
}
|
||||
|
||||
var kind string
|
||||
if preview {
|
||||
kind = "previewed"
|
||||
|
@ -249,19 +251,19 @@ func printChangeSummary(b *bytes.Buffer, counts map[deploy.StepOp]int, preview b
|
|||
}
|
||||
|
||||
var changesLabel string
|
||||
if changes == 0 {
|
||||
if changeCount == 0 {
|
||||
kind = "required"
|
||||
changesLabel = "no"
|
||||
} else {
|
||||
changesLabel = strconv.Itoa(changes)
|
||||
changesLabel = strconv.Itoa(changeCount)
|
||||
}
|
||||
|
||||
if changes > 0 || counts[deploy.OpSame] > 0 {
|
||||
if changeCount > 0 || changes[deploy.OpSame] > 0 {
|
||||
kind += ":"
|
||||
}
|
||||
|
||||
b.WriteString(fmt.Sprintf("%vinfo%v: %v %v %v\n",
|
||||
colors.SpecInfo, colors.Reset, changesLabel, plural("change", changes), kind))
|
||||
colors.SpecInfo, colors.Reset, changesLabel, plural("change", changeCount), kind))
|
||||
|
||||
var planTo string
|
||||
if preview {
|
||||
|
@ -271,7 +273,7 @@ func printChangeSummary(b *bytes.Buffer, counts map[deploy.StepOp]int, preview b
|
|||
// Now summarize all of the changes; we print sames a little differently.
|
||||
for _, op := range deploy.StepOps {
|
||||
if op != deploy.OpSame {
|
||||
if c := counts[op]; c > 0 {
|
||||
if c := changes[op]; c > 0 {
|
||||
opDescription := string(op)
|
||||
if !preview {
|
||||
opDescription = op.PastTense()
|
||||
|
@ -281,11 +283,11 @@ func printChangeSummary(b *bytes.Buffer, counts map[deploy.StepOp]int, preview b
|
|||
}
|
||||
}
|
||||
}
|
||||
if c := counts[deploy.OpSame]; c > 0 {
|
||||
if c := changes[deploy.OpSame]; c > 0 {
|
||||
b.WriteString(fmt.Sprintf(" %v %v unchanged\n", c, plural("resource", c)))
|
||||
}
|
||||
|
||||
return changes
|
||||
return changeCount
|
||||
}
|
||||
|
||||
func plural(s string, c int) string {
|
||||
|
|
Loading…
Reference in a new issue