Ensure destroy plugins are present (#1043)

This change uses the prior checkpoint's deployment manifest to pre-
populate all plugins required to complete the destroy operation.  This
allows for subsequent attempts to load a resource's plugin to match the
already-loaded version.  This approach obviously doesn't work in a
hypothetical future world where plugins for the same resource provider
are loaded side-by-side, but we already know that.
This commit is contained in:
Joe Duffy 2018-03-12 16:27:39 -07:00 committed by GitHub
parent 5b244dbdb1
commit 5924f6b8c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 20 deletions

View file

@ -13,6 +13,7 @@ import (
"strings"
"github.com/opentracing/opentracing-go"
"github.com/sergi/go-diff/diffmatchpatch"
"github.com/pkg/errors"
"github.com/pulumi/pulumi/pkg/diag"
@ -22,7 +23,7 @@ import (
"github.com/pulumi/pulumi/pkg/resource/plugin"
"github.com/pulumi/pulumi/pkg/tokens"
"github.com/pulumi/pulumi/pkg/util/contract"
"github.com/sergi/go-diff/diffmatchpatch"
"github.com/pulumi/pulumi/pkg/workspace"
)
// ProjectInfoContext returns information about the current project, including its pwd, main, and plugin context.
@ -61,12 +62,25 @@ func plan(info *planContext, opts deployOptions) (*planResult, error) {
return nil, err
}
// Figure out which plugins to load. In the case of a destroy, we consult the manifest for the plugin versions
// required to destroy it. Otherwise, we inspect the program contents to figure out which will be required.
var plugins []workspace.PluginInfo
if opts.Destroy {
if target.Snapshot != nil {
plugins = target.Snapshot.Manifest.Plugins
}
} else {
if plugins, err = ctx.Host.GetRequiredPlugins(plugin.ProgInfo{
Proj: proj,
Pwd: pwd,
Program: main,
}); err != nil {
return nil, err
}
}
// Now ensure that we have loaded up any plugins that the program will need in advance.
err = ctx.Host.EnsurePlugins(plugin.ProgInfo{
Proj: proj,
Pwd: pwd,
Program: main,
})
err = ctx.Host.EnsurePlugins(plugins)
if err != nil {
return nil, err
}

View file

@ -380,7 +380,7 @@ func (host *testProviderHost) LanguageRuntime(runtime string) (plugin.LanguageRu
func (host *testProviderHost) ListPlugins() []workspace.PluginInfo {
return nil
}
func (host *testProviderHost) EnsurePlugins(info plugin.ProgInfo) error {
func (host *testProviderHost) EnsurePlugins(plugins []workspace.PluginInfo) error {
return nil
}
func (host *testProviderHost) GetRequiredPlugins(info plugin.ProgInfo) ([]workspace.PluginInfo, error) {

View file

@ -35,9 +35,9 @@ type Host interface {
// ListPlugins lists all plugins that have been loaded, with version information.
ListPlugins() []workspace.PluginInfo
// EnsurePlugins ensures all plugins for the target package are loaded. If any are missing, and/or there are
// errors loading one or more plugins, a non-nil error is returned.
EnsurePlugins(info ProgInfo) error
// EnsurePlugins ensures all plugins in the given array are loaded and ready to use. If any plugins are missing,
// and/or there are errors loading one or more plugins, a non-nil error is returned.
EnsurePlugins(plugins []workspace.PluginInfo) error
// GetRequiredPlugins lists a full set of plugins that will be required by the given program.
GetRequiredPlugins(info ProgInfo) ([]workspace.PluginInfo, error)
@ -261,16 +261,9 @@ func (host *defaultHost) ListPlugins() []workspace.PluginInfo {
return host.plugins
}
// EnsurePlugins ensures all plugins for the target package are loaded. If any are missing, and/or there are
// errors loading one or more plugins, a non-nil error is returned.
func (host *defaultHost) EnsurePlugins(info ProgInfo) error {
// Compute the list of required plugins, and then iterate them and load 'em up. This simultaneously ensures
// they are installed on the system while also loading them into memory for easy subsequent access.
plugins, err := host.GetRequiredPlugins(info)
if err != nil {
return err
}
// EnsurePlugins ensures all plugins in the given array are loaded and ready to use. If any plugins are missing,
// and/or there are errors loading one or more plugins, a non-nil error is returned.
func (host *defaultHost) EnsurePlugins(plugins []workspace.PluginInfo) error {
// Use a multieerror to track failures so we can return one big list of all failures at the end.
var result error
for _, plugin := range plugins {