config: Update loading of packerconfig to only log when a plugin is loaded
Before this change loading of a packerconfig would display `loaded plugin ...` for any plugin defined in the packerconfig - even if it didn't exist on disk. This change updates how plugins defined in packerconfig are loaded to ensure that only successfully loaded plugins get the lovely message `loaded plugin ...`. For any plugin that fails to load Packer will log that it failed to load the plugin and continue processing any other defined plugins. * Add a test to ensure loadSingleComponent errors when plugin does not exists
This commit is contained in:
parent
39c25b2c66
commit
c93a076698
21
config.go
21
config.go
|
@ -61,10 +61,14 @@ func (c *config) LoadExternalComponentsFromConfig() {
|
||||||
|
|
||||||
var externallyUsed = make([]string, 0, len(pluginPaths))
|
var externallyUsed = make([]string, 0, len(pluginPaths))
|
||||||
for _, pluginPath := range pluginPaths {
|
for _, pluginPath := range pluginPaths {
|
||||||
if name, ok := c.loadExternalComponent(pluginPath); ok {
|
name, err := c.loadSingleComponent(pluginPath)
|
||||||
log.Printf("[DEBUG] Loaded plugin: %s = %s", name, pluginPath)
|
if err != nil {
|
||||||
externallyUsed = append(externallyUsed, name)
|
log.Print(err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("loaded plugin: %s = %s", name, pluginPath)
|
||||||
|
externallyUsed = append(externallyUsed, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(externallyUsed) > 0 {
|
if len(externallyUsed) > 0 {
|
||||||
|
@ -73,14 +77,17 @@ func (c *config) LoadExternalComponentsFromConfig() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *config) loadExternalComponent(path string) (string, bool) {
|
func (c *config) loadSingleComponent(path string) (string, error) {
|
||||||
pluginName := filepath.Base(path)
|
pluginName := filepath.Base(path)
|
||||||
|
|
||||||
// On Windows, ignore any plugins that don't end in .exe.
|
// On Windows, ignore any plugins that don't end in .exe.
|
||||||
// We could do a full PATHEXT parse, but this is probably good enough.
|
// We could do a full PATHEXT parse, but this is probably good enough.
|
||||||
if runtime.GOOS == "windows" && strings.ToLower(filepath.Ext(pluginName)) != ".exe" {
|
if runtime.GOOS == "windows" && strings.ToLower(filepath.Ext(pluginName)) != ".exe" {
|
||||||
log.Printf("[DEBUG] Ignoring plugin %s, no exe extension", path)
|
return "", fmt.Errorf("error loading plugin %q, no exe extension", path)
|
||||||
return "", false
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
return "", fmt.Errorf("error loading plugin %q: %s", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the filename has a ".", trim up to there
|
// If the filename has a ".", trim up to there
|
||||||
|
@ -106,7 +113,7 @@ func (c *config) loadExternalComponent(path string) (string, bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pluginName, true
|
return pluginName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discover discovers plugins.
|
// Discover discovers plugins.
|
||||||
|
|
|
@ -63,13 +63,14 @@ func TestLoadExternalComponentsFromConfig(t *testing.T) {
|
||||||
t.Errorf("failed to load external builders; got %v as the resulting config", cfg.Builders)
|
t.Errorf("failed to load external builders; got %v as the resulting config", cfg.Builders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cfg.PostProcessors) != 1 || !cfg.PostProcessors.Has("noop") {
|
||||||
|
t.Errorf("failed to load external post-processors; got %v as the resulting config", cfg.PostProcessors)
|
||||||
|
}
|
||||||
|
|
||||||
if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") {
|
if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") {
|
||||||
t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners)
|
t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.PostProcessors) != 1 || !cfg.PostProcessors.Has("noop") {
|
|
||||||
t.Errorf("failed to load external post-processors; got %v as the resulting config", cfg.PostProcessors)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadExternalComponentsFromConfig_onlyProvisioner(t *testing.T) {
|
func TestLoadExternalComponentsFromConfig_onlyProvisioner(t *testing.T) {
|
||||||
|
@ -94,17 +95,53 @@ func TestLoadExternalComponentsFromConfig_onlyProvisioner(t *testing.T) {
|
||||||
|
|
||||||
cfg.LoadExternalComponentsFromConfig()
|
cfg.LoadExternalComponentsFromConfig()
|
||||||
|
|
||||||
if len(cfg.Builders) != 0 || cfg.Builders.Has("cloud-xyz") {
|
if len(cfg.Builders) != 0 {
|
||||||
t.Errorf("loaded external builders when it wasn't supposed to; got %v as the resulting config", cfg.Builders)
|
t.Errorf("loaded external builders when it wasn't supposed to; got %v as the resulting config", cfg.Builders)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cfg.PostProcessors) != 0 {
|
||||||
|
t.Errorf("loaded external post-processors when it wasn't supposed to; got %v as the resulting config", cfg.PostProcessors)
|
||||||
|
}
|
||||||
|
|
||||||
if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") {
|
if len(cfg.Provisioners) != 1 || !cfg.Provisioners.Has("super-shell") {
|
||||||
t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners)
|
t.Errorf("failed to load external provisioners; got %v as the resulting config", cfg.Provisioners)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(cfg.PostProcessors) != 0 || cfg.PostProcessors.Has("noop") {
|
func TestLoadSingleComponent(t *testing.T) {
|
||||||
t.Errorf("loaded external post-processors when it wasn't supposed to; got %v as the resulting config", cfg.PostProcessors)
|
|
||||||
|
tmpFile, err := ioutil.TempFile(".", "packer-builder-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create test file with error: %s", err)
|
||||||
}
|
}
|
||||||
|
defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
pluginPath string
|
||||||
|
errorExpected bool
|
||||||
|
}{
|
||||||
|
{pluginPath: tmpFile.Name(), errorExpected: false},
|
||||||
|
{pluginPath: "./non-existing-file", errorExpected: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg config
|
||||||
|
cfg.Builders = packer.MapOfBuilder{}
|
||||||
|
cfg.PostProcessors = packer.MapOfPostProcessor{}
|
||||||
|
cfg.Provisioners = packer.MapOfProvisioner{}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
tc := tc
|
||||||
|
_, err := cfg.loadSingleComponent(tc.pluginPath)
|
||||||
|
if tc.errorExpected && err == nil {
|
||||||
|
t.Errorf("expected loadSingleComponent(%s) to error but it didn't", tc.pluginPath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil && !tc.errorExpected {
|
||||||
|
t.Errorf("expected loadSingleComponent(%s) to load properly but got an error: %v", tc.pluginPath, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generateFakePackerConfigData creates a collection of mock plugins along with a basic packerconfig.
|
/* generateFakePackerConfigData creates a collection of mock plugins along with a basic packerconfig.
|
||||||
|
|
Loading…
Reference in New Issue