diff --git a/packer/environment.go b/packer/environment.go index bbf02e764..396dcf9e9 100644 --- a/packer/environment.go +++ b/packer/environment.go @@ -19,13 +19,17 @@ type CommandFunc func(name string) (Command, error) // The function type used to lookup Hook implementations. type HookFunc func(name string) (Hook, error) +// The function type used to lookup Provisioner implementations. +type ProvisionerFunc func(name string) (Provisioner, error) + // ComponentFinder is a struct that contains the various function // pointers necessary to look up components of Packer such as builders, // commands, etc. type ComponentFinder struct { - Builder BuilderFunc - Command CommandFunc - Hook HookFunc + Builder BuilderFunc + Command CommandFunc + Hook HookFunc + Provisioner ProvisionerFunc } // The environment interface provides access to the configuration and @@ -37,6 +41,7 @@ type Environment interface { Builder(string) (Builder, error) Cli([]string) (int, error) Hook(string) (Hook, error) + Provisioner(string) (Provisioner, error) Ui() Ui } @@ -91,6 +96,10 @@ func NewEnvironment(config *EnvironmentConfig) (resultEnv Environment, err error env.components.Hook = func(string) (Hook, error) { return nil, nil } } + if env.components.Provisioner == nil { + env.components.Provisioner = func(string) (Provisioner, error) { return nil, nil } + } + resultEnv = env return } @@ -125,6 +134,21 @@ func (e *coreEnvironment) Hook(name string) (h Hook, err error) { return } +// Returns a provisioner for the given name that is registered with this +// environment. +func (e *coreEnvironment) Provisioner(name string) (p Provisioner, err error) { + p, err = e.components.Provisioner(name) + if err != nil { + return + } + + if p == nil { + err = fmt.Errorf("No provisioner returned for name: %s", name) + } + + return +} + // Executes a command as if it was typed on the command-line interface. // The return value is the exit code of the command. func (e *coreEnvironment) Cli(args []string) (result int, err error) { diff --git a/packer/environment_test.go b/packer/environment_test.go index 08bcc11c3..43aff9854 100644 --- a/packer/environment_test.go +++ b/packer/environment_test.go @@ -67,6 +67,7 @@ func TestEnvironment_NilComponents(t *testing.T) { env.Builder("foo") env.Cli([]string{"foo"}) env.Hook("foo") + env.Provisioner("foo") } func TestEnvironment_Builder(t *testing.T) { @@ -237,6 +238,49 @@ func TestEnvironment_Hook_Error(t *testing.T) { assert.Nil(returned, "should be no hook") } +func TestEnvironmentProvisioner(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + p := &TestProvisioner{} + ps := make(map[string]Provisioner) + ps["foo"] = p + + config := DefaultEnvironmentConfig() + config.Components.Provisioner = func(n string) (Provisioner, error) { return ps[n], nil } + + env, _ := NewEnvironment(config) + returned, err := env.Provisioner("foo") + assert.Nil(err, "should be no error") + assert.Equal(returned, p, "should return correct provisioner") +} + +func TestEnvironmentProvisioner_NilError(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + config := DefaultEnvironmentConfig() + config.Components.Provisioner = func(n string) (Provisioner, error) { return nil, nil } + + env, _ := NewEnvironment(config) + returned, err := env.Provisioner("foo") + assert.NotNil(err, "should be an error") + assert.Nil(returned, "should be no provisioner") +} + +func TestEnvironmentProvisioner_Error(t *testing.T) { + assert := asserts.NewTestingAsserts(t, true) + + config := DefaultEnvironmentConfig() + config.Components.Provisioner = func(n string) (Provisioner, error) { + return nil, errors.New("foo") + } + + env, _ := NewEnvironment(config) + returned, err := env.Provisioner("foo") + assert.NotNil(err, "should be an error") + assert.Equal(err.Error(), "foo", "should be correct error") + assert.Nil(returned, "should be no provisioner") +} + func TestEnvironment_SettingUi(t *testing.T) { assert := asserts.NewTestingAsserts(t, true) diff --git a/packer/provisioner_test.go b/packer/provisioner_test.go new file mode 100644 index 000000000..068473b8a --- /dev/null +++ b/packer/provisioner_test.go @@ -0,0 +1,14 @@ +package packer + +type TestProvisioner struct { + prepCalled bool + provCalled bool +} + +func (t *TestProvisioner) Prepare(interface{}, Ui) { + t.prepCalled = true +} + +func (t *TestProvisioner) Provision(Ui, Communicator) { + t.provCalled = true +}