Commit fbcc6cb2 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: Build now has provisioners, template parses and builds

parent 11d46a3a
...@@ -17,12 +17,20 @@ type Build interface { ...@@ -17,12 +17,20 @@ type Build interface {
type coreBuild struct { type coreBuild struct {
name string name string
builder Builder builder Builder
builderConfig interface{}
hooks map[string][]Hook hooks map[string][]Hook
rawConfig interface{} provisioners []coreBuildProvisioner
prepareCalled bool prepareCalled bool
} }
// Keeps track of the provisioner and the configuration of the provisioner
// within the build.
type coreBuildProvisioner struct {
provisioner Provisioner
config interface{}
}
// Returns the name of the build. // Returns the name of the build.
func (b *coreBuild) Name() string { func (b *coreBuild) Name() string {
return b.name return b.name
...@@ -32,7 +40,7 @@ func (b *coreBuild) Name() string { ...@@ -32,7 +40,7 @@ func (b *coreBuild) Name() string {
// and any hooks. This _must_ be called prior to Run. // and any hooks. This _must_ be called prior to Run.
func (b *coreBuild) Prepare() (err error) { func (b *coreBuild) Prepare() (err error) {
b.prepareCalled = true b.prepareCalled = true
err = b.builder.Prepare(b.rawConfig) err = b.builder.Prepare(b.builderConfig)
if err != nil { if err != nil {
log.Printf("Build '%s' prepare failure: %s\n", b.name, err) log.Printf("Build '%s' prepare failure: %s\n", b.name, err)
} }
......
...@@ -30,7 +30,7 @@ func testBuild() Build { ...@@ -30,7 +30,7 @@ func testBuild() Build {
return &coreBuild{ return &coreBuild{
name: "test", name: "test",
builder: &TestBuilder{}, builder: &TestBuilder{},
rawConfig: 42, builderConfig: 42,
} }
} }
......
...@@ -149,6 +149,7 @@ func (t *Template) BuildNames() []string { ...@@ -149,6 +149,7 @@ func (t *Template) BuildNames() []string {
// If the build does not exist as part of this template, an error is // If the build does not exist as part of this template, an error is
// returned. // returned.
func (t *Template) Build(name string, components *ComponentFinder) (b Build, err error) { func (t *Template) Build(name string, components *ComponentFinder) (b Build, err error) {
// Setup the Builder
builderConfig, ok := t.Builders[name] builderConfig, ok := t.Builders[name]
if !ok { if !ok {
err = fmt.Errorf("No such build found in template: %s", name) err = fmt.Errorf("No such build found in template: %s", name)
...@@ -165,6 +166,7 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err ...@@ -165,6 +166,7 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
return return
} }
// Gather the Hooks
hooks := make(map[string][]Hook) hooks := make(map[string][]Hook)
for tplEvent, tplHooks := range t.Hooks { for tplEvent, tplHooks := range t.Hooks {
curHooks := make([]Hook, 0, len(tplHooks)) curHooks := make([]Hook, 0, len(tplHooks))
...@@ -187,11 +189,30 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err ...@@ -187,11 +189,30 @@ func (t *Template) Build(name string, components *ComponentFinder) (b Build, err
hooks[tplEvent] = curHooks hooks[tplEvent] = curHooks
} }
// Prepare the provisioners
provisioners := make([]coreBuildProvisioner, 0, len(t.Provisioners))
for _, rawProvisioner := range t.Provisioners {
var provisioner Provisioner
provisioner, err = components.Provisioner(rawProvisioner.pType)
if err != nil {
return
}
if provisioner == nil {
err = fmt.Errorf("Provisioner type not found: %s", rawProvisioner.pType)
return
}
coreProv := coreBuildProvisioner{provisioner, rawProvisioner.rawConfig}
provisioners = append(provisioners, coreProv)
}
b = &coreBuild{ b = &coreBuild{
name: name, name: name,
builder: builder, builder: builder,
builderConfig: builderConfig.rawConfig,
hooks: hooks, hooks: hooks,
rawConfig: builderConfig.rawConfig, provisioners: provisioners,
} }
return return
......
...@@ -302,6 +302,12 @@ func TestTemplate_Build(t *testing.T) { ...@@ -302,6 +302,12 @@ func TestTemplate_Build(t *testing.T) {
"name": "test1", "name": "test1",
"type": "test-builder" "type": "test-builder"
} }
],
"provisioners": [
{
"type": "test-prov"
}
] ]
} }
` `
...@@ -319,18 +325,26 @@ func TestTemplate_Build(t *testing.T) { ...@@ -319,18 +325,26 @@ func TestTemplate_Build(t *testing.T) {
"test-builder": builder, "test-builder": builder,
} }
provisioner := &TestProvisioner{}
provisionerMap := map[string]Provisioner{
"test-prov": provisioner,
}
builderFactory := func(n string) (Builder, error) { return builderMap[n], nil } builderFactory := func(n string) (Builder, error) { return builderMap[n], nil }
components := &ComponentFinder{Builder: builderFactory} provFactory := func(n string) (Provisioner, error) { return provisionerMap[n], nil }
components := &ComponentFinder{
Builder: builderFactory,
Provisioner: provFactory,
}
// Get the build, verifying we can get it without issue, but also // Get the build, verifying we can get it without issue, but also
// that the proper builder was looked up and used for the build. // that the proper builder was looked up and used for the build.
build, err := template.Build("test1", components) build, err := template.Build("test1", components)
assert.Nil(err, "should not error") assert.Nil(err, "should not error")
build.Prepare() coreBuild, ok := build.(*coreBuild)
build.Run(testUi()) assert.True(ok, "should be a core build")
assert.Equal(coreBuild.builder, builder, "should have the same builder")
assert.True(builder.prepareCalled, "prepare should be called") assert.Equal(coreBuild.builderConfig, expectedConfig, "should have proper config")
assert.Equal(builder.prepareConfig, expectedConfig, "prepare config should be correct") assert.Equal(len(coreBuild.provisioners), 1, "should have one provisioner")
assert.True(builder.runCalled, "run should be called")
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment