2017-08-30 03:24:12 +02:00
|
|
|
// Copyright 2017, Pulumi Corporation. All rights reserved.
|
|
|
|
|
2017-08-23 01:56:15 +02:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
2017-09-07 16:25:08 +02:00
|
|
|
goerr "github.com/pkg/errors"
|
|
|
|
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/compiler/errors"
|
|
|
|
"github.com/pulumi/pulumi/pkg/diag"
|
|
|
|
"github.com/pulumi/pulumi/pkg/diag/colors"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/deploy"
|
|
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
2017-08-23 01:56:15 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type DeployOptions struct {
|
|
|
|
Package string // the package we are deploying (or "" to use the default)
|
2017-08-24 01:57:03 +02:00
|
|
|
Analyzers []string // an optional set of analyzers to run as part of this deployment.
|
2017-08-23 01:56:15 +02:00
|
|
|
DryRun bool // true if we should just print the plan without performing it.
|
2017-09-17 17:10:46 +02:00
|
|
|
Parallel int // the degree of parallelism for resource operations (<=1 for serial).
|
2017-08-23 01:56:15 +02:00
|
|
|
ShowConfig bool // true to show the configuration variables being used.
|
|
|
|
ShowReplacementSteps bool // true to show the replacement steps in the plan.
|
|
|
|
ShowSames bool // true to show the resources that aren't updated, in addition to those that are.
|
|
|
|
Summary bool // true if we should only summarize resources and operations.
|
|
|
|
}
|
|
|
|
|
2017-10-16 21:04:35 +02:00
|
|
|
func (eng *Engine) Deploy(stack tokens.QName, events chan<- Event, opts DeployOptions) error {
|
|
|
|
contract.Require(stack != tokens.QName(""), "stack")
|
2017-10-05 23:08:46 +02:00
|
|
|
contract.Require(events != nil, "events")
|
2017-09-09 22:43:51 +02:00
|
|
|
|
2017-10-23 00:52:00 +02:00
|
|
|
defer func() { events <- cancelEvent() }()
|
|
|
|
|
2017-10-16 21:04:35 +02:00
|
|
|
info, err := eng.planContextFromStack(stack, opts.Package)
|
2017-08-23 01:56:15 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-09 02:08:51 +01:00
|
|
|
defer info.Close()
|
2017-10-05 23:08:46 +02:00
|
|
|
|
2017-08-23 19:58:35 +02:00
|
|
|
return eng.deployLatest(info, deployOptions{
|
2017-08-23 01:56:15 +02:00
|
|
|
Destroy: false,
|
|
|
|
DryRun: opts.DryRun,
|
|
|
|
Analyzers: opts.Analyzers,
|
2017-09-17 17:10:46 +02:00
|
|
|
Parallel: opts.Parallel,
|
2017-08-23 01:56:15 +02:00
|
|
|
ShowConfig: opts.ShowConfig,
|
|
|
|
ShowReplacementSteps: opts.ShowReplacementSteps,
|
|
|
|
ShowSames: opts.ShowSames,
|
|
|
|
Summary: opts.Summary,
|
2017-10-05 23:08:46 +02:00
|
|
|
Events: events,
|
2017-10-23 00:22:15 +02:00
|
|
|
Diag: newEventSink(events, diag.FormatOptions{
|
|
|
|
Colors: true,
|
|
|
|
}),
|
2017-08-23 01:56:15 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type deployOptions struct {
|
2017-10-12 23:16:44 +02:00
|
|
|
Create bool // true if we are creating resources.
|
2017-10-16 21:04:35 +02:00
|
|
|
Destroy bool // true if we are destroying the stack.
|
2017-10-12 23:16:44 +02:00
|
|
|
DryRun bool // true if we should just print the plan without performing it.
|
|
|
|
Analyzers []string // an optional set of analyzers to run as part of this deployment.
|
|
|
|
Parallel int // the degree of parallelism for resource operations (<=1 for serial).
|
|
|
|
ShowConfig bool // true to show the configuration variables being used.
|
|
|
|
ShowReplacementSteps bool // true to show the replacement steps in the plan.
|
|
|
|
ShowSames bool // true to show the resources that aren't updated, in addition to those that are.
|
|
|
|
Summary bool // true if we should only summarize resources and operations.
|
2017-11-17 03:21:41 +01:00
|
|
|
Detailed bool // true to show very detailed output, like properties that haven't changed.
|
2017-10-12 23:16:44 +02:00
|
|
|
DOT bool // true if we should print the DOT file for this plan.
|
|
|
|
Events chan<- Event // the channel to write events from the engine to.
|
|
|
|
Diag diag.Sink // the sink to use for diag'ing.
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|
|
|
|
|
2017-10-03 02:27:55 +02:00
|
|
|
func (eng *Engine) deployLatest(info *planContext, opts deployOptions) error {
|
2017-08-23 19:58:35 +02:00
|
|
|
result, err := eng.plan(info, opts)
|
2017-08-23 01:56:15 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if result != nil {
|
|
|
|
defer contract.IgnoreClose(result)
|
2017-12-12 21:31:09 +01:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
defer done()
|
|
|
|
|
2017-08-23 01:56:15 +02:00
|
|
|
if opts.DryRun {
|
|
|
|
// If a dry run, just print the plan, don't actually carry out the deployment.
|
2017-09-17 17:10:46 +02:00
|
|
|
if err := eng.printPlan(result); err != nil {
|
2017-08-23 01:56:15 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Otherwise, we will actually deploy the latest bits.
|
|
|
|
var header bytes.Buffer
|
2017-09-17 17:10:46 +02:00
|
|
|
printPrelude(&header, result, false)
|
2017-09-23 02:23:40 +02:00
|
|
|
header.WriteString(fmt.Sprintf("%vPerforming changes:%v\n", colors.SpecUnimportant, colors.Reset))
|
2017-10-05 23:08:46 +02:00
|
|
|
opts.Events <- stdOutEventWithColor(&header)
|
2017-08-23 01:56:15 +02:00
|
|
|
|
2017-10-02 23:26:51 +02:00
|
|
|
// Walk the plan, reporting progress and executing the actual operations as we go.
|
2017-08-23 01:56:15 +02:00
|
|
|
start := time.Now()
|
2017-11-17 03:21:41 +01:00
|
|
|
actions := newDeployActions(opts, result.Info.Target, eng)
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
summary, _, _, err := result.Walk(actions, false)
|
2017-08-27 09:38:17 +02:00
|
|
|
if err != nil && summary == nil {
|
2017-10-03 20:07:36 +02:00
|
|
|
// Something went wrong, and no changes were made.
|
2017-08-27 09:38:17 +02:00
|
|
|
return err
|
|
|
|
}
|
2017-08-23 01:56:15 +02:00
|
|
|
contract.Assert(summary != nil)
|
|
|
|
|
|
|
|
// Print a summary.
|
|
|
|
var footer bytes.Buffer
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
|
2017-08-23 01:56:15 +02:00
|
|
|
// Print out the total number of steps performed (and their kinds), the duration, and any summary info.
|
2017-10-02 23:26:51 +02:00
|
|
|
if c := printChangeSummary(&footer, actions.Ops, false); c != 0 {
|
2017-09-23 02:23:40 +02:00
|
|
|
footer.WriteString(fmt.Sprintf("%vUpdate duration: %v%v\n",
|
2017-08-23 01:56:15 +02:00
|
|
|
colors.SpecUnimportant, time.Since(start), colors.Reset))
|
|
|
|
}
|
|
|
|
|
2017-10-02 23:26:51 +02:00
|
|
|
if actions.MaybeCorrupt {
|
2017-08-23 01:56:15 +02:00
|
|
|
footer.WriteString(fmt.Sprintf(
|
|
|
|
"%vA catastrophic error occurred; resources states may be unknown%v\n",
|
|
|
|
colors.SpecAttention, colors.Reset))
|
|
|
|
}
|
|
|
|
|
2017-10-05 23:08:46 +02:00
|
|
|
opts.Events <- stdOutEventWithColor(&footer)
|
|
|
|
|
2017-09-09 21:42:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|
|
|
|
}
|
2017-10-05 23:08:46 +02:00
|
|
|
if !opts.Diag.Success() {
|
2017-09-06 18:35:35 +02:00
|
|
|
// If any error that wasn't printed above, be sure to make it evident in the output.
|
2017-09-23 02:23:40 +02:00
|
|
|
return goerr.New("One or more errors occurred during this update")
|
2017-09-06 18:35:35 +02:00
|
|
|
}
|
2017-08-23 01:56:15 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-10-02 23:26:51 +02:00
|
|
|
// deployActions pretty-prints the plan application process as it goes.
|
|
|
|
type deployActions struct {
|
2017-08-23 01:56:15 +02:00
|
|
|
Steps int
|
|
|
|
Ops map[deploy.StepOp]int
|
2017-11-17 03:21:41 +01:00
|
|
|
Seen map[resource.URN]deploy.Step
|
|
|
|
Shown map[resource.URN]bool
|
2017-08-23 01:56:15 +02:00
|
|
|
MaybeCorrupt bool
|
|
|
|
Opts deployOptions
|
2017-10-02 23:27:50 +02:00
|
|
|
Target *deploy.Target
|
2017-08-23 19:58:35 +02:00
|
|
|
Engine *Engine
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|
|
|
|
|
2017-11-17 03:21:41 +01:00
|
|
|
func newDeployActions(opts deployOptions, target *deploy.Target, engine *Engine) *deployActions {
|
|
|
|
return &deployActions{
|
|
|
|
Ops: make(map[deploy.StepOp]int),
|
|
|
|
Seen: make(map[resource.URN]deploy.Step),
|
|
|
|
Shown: make(map[resource.URN]bool),
|
|
|
|
Opts: opts,
|
|
|
|
Target: target,
|
|
|
|
Engine: engine,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
func (acts *deployActions) OnResourceStepPre(step deploy.Step) (interface{}, error) {
|
2017-10-03 19:27:59 +02:00
|
|
|
// Report the beginning of the step if appropriate.
|
2017-12-07 22:33:16 +01:00
|
|
|
if shouldShow(acts.Seen, step, acts.Opts) || isRootStack(step) {
|
2017-10-02 23:26:51 +02:00
|
|
|
var b bytes.Buffer
|
2017-11-17 03:21:41 +01:00
|
|
|
printStep(&b, step, acts.Seen, acts.Shown, acts.Opts.Summary, acts.Opts.Detailed, false, 0 /*indent*/)
|
2017-10-05 23:08:46 +02:00
|
|
|
acts.Opts.Events <- stdOutEventWithColor(&b)
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|
|
|
|
|
2017-10-21 18:31:01 +02:00
|
|
|
// Inform the snapshot service that we are about to perform a step.
|
2017-12-07 22:33:16 +01:00
|
|
|
if step.Op() != deploy.OpSame {
|
|
|
|
return acts.Engine.Snapshots.BeginMutation(acts.Target.Name)
|
|
|
|
}
|
|
|
|
return nil, nil
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
}
|
2017-08-23 01:56:15 +02:00
|
|
|
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
func (acts *deployActions) OnResourceStepPost(ctx interface{},
|
2017-11-30 00:05:58 +01:00
|
|
|
step deploy.Step, status resource.Status, err error) error {
|
2017-11-29 20:27:32 +01:00
|
|
|
var b bytes.Buffer
|
|
|
|
|
2017-10-03 19:27:59 +02:00
|
|
|
// Report the result of the step.
|
2017-08-23 01:56:15 +02:00
|
|
|
stepop := step.Op()
|
|
|
|
if err != nil {
|
|
|
|
// Issue a true, bonafide error.
|
2017-10-05 23:08:46 +02:00
|
|
|
acts.Opts.Diag.Errorf(errors.ErrorPlanApplyFailed, err)
|
2017-08-23 01:56:15 +02:00
|
|
|
|
|
|
|
// Print the state of the resource; we don't issue the error, because the deploy above will do that.
|
2017-10-02 23:26:51 +02:00
|
|
|
stepnum := acts.Steps + 1
|
2017-08-23 01:56:15 +02:00
|
|
|
b.WriteString(fmt.Sprintf("Step #%v failed [%v]: ", stepnum, stepop))
|
|
|
|
switch status {
|
|
|
|
case resource.StatusOK:
|
|
|
|
b.WriteString(colors.SpecNote)
|
|
|
|
b.WriteString("provider successfully recovered from this failure")
|
|
|
|
case resource.StatusUnknown:
|
|
|
|
b.WriteString(colors.SpecAttention)
|
|
|
|
b.WriteString("this failure was catastrophic and the provider cannot guarantee recovery")
|
2017-10-02 23:26:51 +02:00
|
|
|
acts.MaybeCorrupt = true
|
2017-08-23 01:56:15 +02:00
|
|
|
default:
|
|
|
|
contract.Failf("Unrecognized resource state: %v", status)
|
|
|
|
}
|
|
|
|
b.WriteString(colors.Reset)
|
|
|
|
b.WriteString("\n")
|
2017-11-29 20:27:32 +01:00
|
|
|
} else {
|
|
|
|
if step.Logical() {
|
|
|
|
// Increment the counters.
|
|
|
|
acts.Steps++
|
|
|
|
acts.Ops[stepop]++
|
|
|
|
}
|
|
|
|
|
|
|
|
// Also show outputs here, since there might be some from the initial registration.
|
2017-12-07 22:33:16 +01:00
|
|
|
if shouldShow(acts.Seen, step, acts.Opts) && !acts.Opts.Summary {
|
|
|
|
printResourceOutputProperties(&b, step, acts.Seen, acts.Shown, 0 /*indent*/)
|
|
|
|
}
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|
2017-10-02 23:27:50 +02:00
|
|
|
|
2017-11-29 20:27:32 +01:00
|
|
|
acts.Opts.Events <- stdOutEventWithColor(&b)
|
|
|
|
|
2017-11-21 02:38:09 +01:00
|
|
|
// If necessary, write out the current snapshot. Note that even if a failure has occurred, we should still have a
|
|
|
|
// safe checkpoint. Note that any error that occurs when writing the checkpoint trumps the error reported above.
|
2017-12-07 22:33:16 +01:00
|
|
|
if ctx != nil {
|
|
|
|
return ctx.(SnapshotMutation).End(step.Iterator().Snap())
|
|
|
|
}
|
|
|
|
return nil
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
}
|
2017-10-03 19:27:59 +02:00
|
|
|
|
2017-11-30 00:05:58 +01:00
|
|
|
func (acts *deployActions) OnResourceOutputs(step deploy.Step) error {
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
// Print this step's output properties.
|
2017-12-07 22:33:16 +01:00
|
|
|
if (shouldShow(acts.Seen, step, acts.Opts) || isRootStack(step)) && !acts.Opts.Summary {
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
var b bytes.Buffer
|
|
|
|
printResourceOutputProperties(&b, step, acts.Seen, acts.Shown, 0 /*indent*/)
|
|
|
|
acts.Opts.Events <- stdOutEventWithColor(&b)
|
|
|
|
}
|
2017-11-29 17:36:04 +01:00
|
|
|
|
2017-11-30 00:05:58 +01:00
|
|
|
// There's a chance there are new outputs that weren't written out last time.
|
2017-11-29 17:36:04 +01:00
|
|
|
// We need to perform another snapshot write to ensure they get written out.
|
2017-11-30 00:05:58 +01:00
|
|
|
mutation, err := acts.Engine.Snapshots.BeginMutation(acts.Target.Name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err = mutation.End(step.Iterator().Snap()); err != nil {
|
|
|
|
return err
|
2017-11-29 17:36:04 +01:00
|
|
|
}
|
|
|
|
|
Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:
* Instead of RegisterResource and CompleteResource, we call these
BeginRegisterResource and EndRegisterResource, which begins to model
these as effectively "asynchronous" resource requests. This should also
help with parallelism (https://github.com/pulumi/pulumi/issues/106).
* Flip the CLI/engine a little on its head. Rather than it driving the
planning and deployment process, we move more to a model where it
simply observes it. This is done by implementing an event handler
interface with three events: OnResourceStepPre, OnResourceStepPost,
and OnResourceComplete. The first two are invoked immediately before
and after any step operation, and the latter is invoked whenever a
EndRegisterResource comes in. The reason for the asymmetry here is
that the checkpointing logic in the deployment engine is largely
untouched (intentionally, as this is a sensitive part of the system),
and so the "begin"/"end" nature doesn't flow through faithfully.
* Also make the engine more event-oriented in its terminology and the
way it handles the incoming BeginRegisterResource and
EndRegisterResource events from the language host. This is the first
step down a long road of incrementally refactoring the engine to work
this way, a necessary prerequisite for parallelism.
2017-11-29 16:42:14 +01:00
|
|
|
return nil
|
2017-08-23 01:56:15 +02:00
|
|
|
}
|