2017-09-23 00:15:42 +02:00
|
|
|
// Copyright 2017, Pulumi Corporation. All rights reserved.
|
|
|
|
|
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
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
|
|
|
"bytes"
|
|
|
|
|
2017-09-23 00:15:42 +02:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/pulumi/pulumi/pkg/diag"
|
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
|
|
|
"github.com/pulumi/pulumi/pkg/resource"
|
|
|
|
"github.com/pulumi/pulumi/pkg/resource/deploy"
|
2017-09-23 00:15:42 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PreviewOptions struct {
|
|
|
|
Package string // the package to compute the preview for
|
|
|
|
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-10-16 21:04:35 +02:00
|
|
|
func (eng *Engine) Preview(stack tokens.QName, events chan<- Event, opts PreviewOptions) error {
|
|
|
|
contract.Require(stack != tokens.QName(""), "stack")
|
2017-10-05 23:08:46 +02:00
|
|
|
contract.Require(events != nil, "events")
|
2017-09-23 00:15:42 +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-09-23 00:15:42 +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-10-23 00:22:15 +02:00
|
|
|
return eng.previewLatest(info, deployOptions{
|
2017-09-23 00:15:42 +02:00
|
|
|
Destroy: false,
|
|
|
|
DryRun: true,
|
|
|
|
Analyzers: opts.Analyzers,
|
|
|
|
Parallel: opts.Parallel,
|
|
|
|
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-10-17 05:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (eng *Engine) previewLatest(info *planContext, opts deployOptions) error {
|
|
|
|
result, err := eng.plan(info, opts)
|
2017-09-23 00:15:42 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if result != nil {
|
|
|
|
defer contract.IgnoreClose(result)
|
|
|
|
if err := eng.printPlan(result); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2017-10-17 05:51:18 +02:00
|
|
|
if !opts.Diag.Success() {
|
2017-09-23 00:15:42 +02:00
|
|
|
// If any error occurred while walking the plan, be sure to let the developer know. Otherwise,
|
|
|
|
// although error messages may have spewed to the output, the final lines of the plan may look fine.
|
2017-09-23 02:23:40 +02:00
|
|
|
return errors.New("One or more errors occurred during the creation of this preview")
|
2017-09-23 00:15:42 +02:00
|
|
|
}
|
|
|
|
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-17 05:51:18 +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
|
|
|
type previewActions struct {
|
|
|
|
Summary bytes.Buffer
|
|
|
|
Ops map[deploy.StepOp]int
|
|
|
|
Opts deployOptions
|
|
|
|
Seen map[resource.URN]deploy.Step
|
|
|
|
Shown map[resource.URN]bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func newPreviewActions(opts deployOptions) *previewActions {
|
|
|
|
return &previewActions{
|
|
|
|
Ops: make(map[deploy.StepOp]int),
|
|
|
|
Opts: opts,
|
|
|
|
Seen: make(map[resource.URN]deploy.Step),
|
|
|
|
Shown: make(map[resource.URN]bool),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (acts *previewActions) OnResourceStepPre(step deploy.Step) (interface{}, error) {
|
|
|
|
// Print this step information (resource and all its properties).
|
|
|
|
if shouldShow(acts.Seen, step, acts.Opts) {
|
|
|
|
printStep(&acts.Summary, step,
|
|
|
|
acts.Seen, acts.Shown, acts.Opts.Summary, acts.Opts.Detailed, true, 0 /*indent*/)
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (acts *previewActions) OnResourceStepPost(ctx interface{},
|
2017-11-30 00:05:58 +01:00
|
|
|
step deploy.Step, status resource.Status, err error) 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
|
|
|
// We let `printPlan` handle error reporting for now.
|
|
|
|
if err == nil {
|
|
|
|
// Track the operation if shown and/or if it is a logically meaningful operation.
|
|
|
|
if step.Logical() {
|
|
|
|
acts.Ops[step.Op()]++
|
|
|
|
}
|
2017-11-29 20:27:32 +01:00
|
|
|
|
|
|
|
// Also show outputs here, since there might be some from the initial registration.
|
2017-11-30 00:05:58 +01:00
|
|
|
_ = acts.OnResourceOutputs(step)
|
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-11-30 00:05:58 +01:00
|
|
|
func (acts *previewActions) 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.
|
|
|
|
if shouldShow(acts.Seen, step, acts.Opts) && !acts.Opts.Summary {
|
|
|
|
printResourceOutputProperties(&acts.Summary, step, acts.Seen, acts.Shown, 0 /*indent*/)
|
|
|
|
}
|
|
|
|
return nil
|
2017-09-23 00:15:42 +02:00
|
|
|
}
|