packer: builder prepare can return warnings
This commit is contained in:
parent
24db112b79
commit
336051e316
|
@ -38,8 +38,9 @@ type Build interface {
|
||||||
Name() string
|
Name() string
|
||||||
|
|
||||||
// Prepare configures the various components of this build and reports
|
// Prepare configures the various components of this build and reports
|
||||||
// any errors in doing so (such as syntax errors, validation errors, etc.)
|
// any errors in doing so (such as syntax errors, validation errors, etc.).
|
||||||
Prepare(v map[string]string) error
|
// It also reports any warnings.
|
||||||
|
Prepare(v map[string]string) ([]string, error)
|
||||||
|
|
||||||
// Run runs the actual builder, returning an artifact implementation
|
// Run runs the actual builder, returning an artifact implementation
|
||||||
// of what is built. If anything goes wrong, an error is returned.
|
// of what is built. If anything goes wrong, an error is returned.
|
||||||
|
@ -115,7 +116,7 @@ func (b *coreBuild) Name() string {
|
||||||
// Prepare prepares the build by doing some initialization for the builder
|
// Prepare prepares the build by doing some initialization for the builder
|
||||||
// and any hooks. This _must_ be called prior to Run. The parameter is the
|
// and any hooks. This _must_ be called prior to Run. The parameter is the
|
||||||
// overrides for the variables within the template (if any).
|
// overrides for the variables within the template (if any).
|
||||||
func (b *coreBuild) Prepare(userVars map[string]string) (err error) {
|
func (b *coreBuild) Prepare(userVars map[string]string) (warn []string, err error) {
|
||||||
b.l.Lock()
|
b.l.Lock()
|
||||||
defer b.l.Unlock()
|
defer b.l.Unlock()
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ func (b *coreBuild) Prepare(userVars map[string]string) (err error) {
|
||||||
// If there were any problem with variables, return an error right
|
// If there were any problem with variables, return an error right
|
||||||
// away because we can't be certain anything else will actually work.
|
// away because we can't be certain anything else will actually work.
|
||||||
if len(varErrs) > 0 {
|
if len(varErrs) > 0 {
|
||||||
return &MultiError{
|
return nil, &MultiError{
|
||||||
Errors: varErrs,
|
Errors: varErrs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,7 +169,7 @@ func (b *coreBuild) Prepare(userVars map[string]string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the builder
|
// Prepare the builder
|
||||||
err = b.builder.Prepare(b.builderConfig, packerConfig)
|
warn, err = b.builder.Prepare(b.builderConfig, packerConfig)
|
||||||
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)
|
||||||
return
|
return
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
func testBuild() *coreBuild {
|
func testBuild() *coreBuild {
|
||||||
return &coreBuild{
|
return &coreBuild{
|
||||||
name: "test",
|
name: "test",
|
||||||
builder: &TestBuilder{artifactId: "b"},
|
builder: &MockBuilder{ArtifactId: "b"},
|
||||||
builderConfig: 42,
|
builderConfig: 42,
|
||||||
builderType: "foo",
|
builderType: "foo",
|
||||||
hooks: map[string][]Hook{
|
hooks: map[string][]Hook{
|
||||||
|
@ -26,10 +26,6 @@ func testBuild() *coreBuild {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBuilder() *TestBuilder {
|
|
||||||
return &TestBuilder{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testDefaultPackerConfig() map[string]interface{} {
|
func testDefaultPackerConfig() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
BuildNameConfigKey: "test",
|
BuildNameConfigKey: "test",
|
||||||
|
@ -50,14 +46,14 @@ func TestBuild_Prepare(t *testing.T) {
|
||||||
packerConfig := testDefaultPackerConfig()
|
packerConfig := testDefaultPackerConfig()
|
||||||
|
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
|
|
||||||
build.Prepare(nil)
|
build.Prepare(nil)
|
||||||
if !builder.prepareCalled {
|
if !builder.PrepareCalled {
|
||||||
t.Fatal("should be called")
|
t.Fatal("should be called")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(builder.prepareConfig, []interface{}{42, packerConfig}) {
|
if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
|
||||||
t.Fatalf("bad: %#v", builder.prepareConfig)
|
t.Fatalf("bad: %#v", builder.PrepareConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
coreProv := build.provisioners[0]
|
coreProv := build.provisioners[0]
|
||||||
|
@ -81,7 +77,11 @@ func TestBuild_Prepare(t *testing.T) {
|
||||||
|
|
||||||
func TestBuild_Prepare_Twice(t *testing.T) {
|
func TestBuild_Prepare_Twice(t *testing.T) {
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
if err := build.Prepare(nil); err != nil {
|
warn, err := build.Prepare(nil)
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("bad error: %s", err)
|
t.Fatalf("bad error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,20 +99,36 @@ func TestBuild_Prepare_Twice(t *testing.T) {
|
||||||
build.Prepare(nil)
|
build.Prepare(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildPrepare_BuilderWarniings(t *testing.T) {
|
||||||
|
expected := []string{"foo"}
|
||||||
|
|
||||||
|
build := testBuild()
|
||||||
|
builder := build.builder.(*MockBuilder)
|
||||||
|
builder.PrepareWarnings = expected
|
||||||
|
|
||||||
|
warn, err := build.Prepare(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(warn, expected) {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuild_Prepare_Debug(t *testing.T) {
|
func TestBuild_Prepare_Debug(t *testing.T) {
|
||||||
packerConfig := testDefaultPackerConfig()
|
packerConfig := testDefaultPackerConfig()
|
||||||
packerConfig[DebugConfigKey] = true
|
packerConfig[DebugConfigKey] = true
|
||||||
|
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
|
|
||||||
build.SetDebug(true)
|
build.SetDebug(true)
|
||||||
build.Prepare(nil)
|
build.Prepare(nil)
|
||||||
if !builder.prepareCalled {
|
if !builder.PrepareCalled {
|
||||||
t.Fatalf("should be called")
|
t.Fatalf("should be called")
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(builder.prepareConfig, []interface{}{42, packerConfig}) {
|
if !reflect.DeepEqual(builder.PrepareConfig, []interface{}{42, packerConfig}) {
|
||||||
t.Fatalf("bad: %#v", builder.prepareConfig)
|
t.Fatalf("bad: %#v", builder.PrepareConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
coreProv := build.provisioners[0]
|
coreProv := build.provisioners[0]
|
||||||
|
@ -133,19 +149,22 @@ func TestBuildPrepare_variables_default(t *testing.T) {
|
||||||
|
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
|
|
||||||
err := build.Prepare(nil)
|
warn, err := build.Prepare(nil)
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !builder.prepareCalled {
|
if !builder.PrepareCalled {
|
||||||
t.Fatal("prepare should be called")
|
t.Fatal("prepare should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(builder.prepareConfig[1], packerConfig) {
|
if !reflect.DeepEqual(builder.PrepareConfig[1], packerConfig) {
|
||||||
t.Fatalf("prepare bad: %#v", builder.prepareConfig[1])
|
t.Fatalf("prepare bad: %#v", builder.PrepareConfig[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +172,10 @@ func TestBuildPrepare_variables_nonexist(t *testing.T) {
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
||||||
|
|
||||||
err := build.Prepare(map[string]string{"bar": "baz"})
|
warn, err := build.Prepare(map[string]string{"bar": "baz"})
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("should have had error")
|
t.Fatal("should have had error")
|
||||||
}
|
}
|
||||||
|
@ -167,19 +189,22 @@ func TestBuildPrepare_variables_override(t *testing.T) {
|
||||||
|
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
build.variables["foo"] = coreBuildVariable{Default: "bar"}
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
|
|
||||||
err := build.Prepare(map[string]string{"foo": "baz"})
|
warn, err := build.Prepare(map[string]string{"foo": "baz"})
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !builder.prepareCalled {
|
if !builder.PrepareCalled {
|
||||||
t.Fatal("prepare should be called")
|
t.Fatal("prepare should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(builder.prepareConfig[1], packerConfig) {
|
if !reflect.DeepEqual(builder.PrepareConfig[1], packerConfig) {
|
||||||
t.Fatalf("prepare bad: %#v", builder.prepareConfig[1])
|
t.Fatalf("prepare bad: %#v", builder.PrepareConfig[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +212,10 @@ func TestBuildPrepare_variablesRequired(t *testing.T) {
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
build.variables["foo"] = coreBuildVariable{Required: true}
|
build.variables["foo"] = coreBuildVariable{Required: true}
|
||||||
|
|
||||||
err := build.Prepare(map[string]string{})
|
warn, err := build.Prepare(map[string]string{})
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("should have had error")
|
t.Fatal("should have had error")
|
||||||
}
|
}
|
||||||
|
@ -195,7 +223,10 @@ func TestBuildPrepare_variablesRequired(t *testing.T) {
|
||||||
// Test with setting the value
|
// Test with setting the value
|
||||||
build = testBuild()
|
build = testBuild()
|
||||||
build.variables["foo"] = coreBuildVariable{Required: true}
|
build.variables["foo"] = coreBuildVariable{Required: true}
|
||||||
err = build.Prepare(map[string]string{"foo": ""})
|
warn, err = build.Prepare(map[string]string{"foo": ""})
|
||||||
|
if len(warn) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", warn)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -216,13 +247,13 @@ func TestBuild_Run(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify builder was run
|
// Verify builder was run
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
if !builder.runCalled {
|
if !builder.RunCalled {
|
||||||
t.Fatal("should be called")
|
t.Fatal("should be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify hooks are disapatchable
|
// Verify hooks are disapatchable
|
||||||
dispatchHook := builder.runHook
|
dispatchHook := builder.RunHook
|
||||||
dispatchHook.Run("foo", nil, nil, 42)
|
dispatchHook.Run("foo", nil, nil, 42)
|
||||||
|
|
||||||
hook := build.hooks["foo"][0].(*MockHook)
|
hook := build.hooks["foo"][0].(*MockHook)
|
||||||
|
@ -402,8 +433,8 @@ func TestBuild_Cancel(t *testing.T) {
|
||||||
build := testBuild()
|
build := testBuild()
|
||||||
build.Cancel()
|
build.Cancel()
|
||||||
|
|
||||||
builder := build.builder.(*TestBuilder)
|
builder := build.builder.(*MockBuilder)
|
||||||
if !builder.cancelCalled {
|
if !builder.CancelCalled {
|
||||||
t.Fatal("cancel should be called")
|
t.Fatal("cancel should be called")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,10 @@ type Builder interface {
|
||||||
//
|
//
|
||||||
// Each of the configuration values should merge into the final
|
// Each of the configuration values should merge into the final
|
||||||
// configuration.
|
// configuration.
|
||||||
Prepare(...interface{}) error
|
//
|
||||||
|
// Prepare should return a list of warnings along with any errors
|
||||||
|
// that occured while preparing.
|
||||||
|
Prepare(...interface{}) ([]string, error)
|
||||||
|
|
||||||
// Run is where the actual build should take place. It takes a Build and a Ui.
|
// Run is where the actual build should take place. It takes a Build and a Ui.
|
||||||
Run(ui Ui, hook Hook, cache Cache) (Artifact, error)
|
Run(ui Ui, hook Hook, cache Cache) (Artifact, error)
|
||||||
|
|
|
@ -4,7 +4,8 @@ package packer
|
||||||
// You can set some fake return values and you can keep track of what
|
// You can set some fake return values and you can keep track of what
|
||||||
// methods were called on the builder. It is fairly basic.
|
// methods were called on the builder. It is fairly basic.
|
||||||
type MockBuilder struct {
|
type MockBuilder struct {
|
||||||
ArtifactId string
|
ArtifactId string
|
||||||
|
PrepareWarnings []string
|
||||||
|
|
||||||
PrepareCalled bool
|
PrepareCalled bool
|
||||||
PrepareConfig []interface{}
|
PrepareConfig []interface{}
|
||||||
|
@ -15,10 +16,10 @@ type MockBuilder struct {
|
||||||
CancelCalled bool
|
CancelCalled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tb *MockBuilder) Prepare(config ...interface{}) error {
|
func (tb *MockBuilder) Prepare(config ...interface{}) ([]string, error) {
|
||||||
tb.PrepareCalled = true
|
tb.PrepareCalled = true
|
||||||
tb.PrepareConfig = config
|
tb.PrepareConfig = config
|
||||||
return nil
|
return tb.PrepareWarnings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tb *MockBuilder) Run(ui Ui, h Hook, c Cache) (Artifact, error) {
|
func (tb *MockBuilder) Run(ui Ui, h Hook, c Cache) (Artifact, error) {
|
||||||
|
|
|
@ -1,31 +1 @@
|
||||||
package packer
|
package packer
|
||||||
|
|
||||||
type TestBuilder struct {
|
|
||||||
artifactId string
|
|
||||||
|
|
||||||
prepareCalled bool
|
|
||||||
prepareConfig []interface{}
|
|
||||||
runCalled bool
|
|
||||||
runCache Cache
|
|
||||||
runHook Hook
|
|
||||||
runUi Ui
|
|
||||||
cancelCalled bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tb *TestBuilder) Prepare(config ...interface{}) error {
|
|
||||||
tb.prepareCalled = true
|
|
||||||
tb.prepareConfig = config
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tb *TestBuilder) Run(ui Ui, h Hook, c Cache) (Artifact, error) {
|
|
||||||
tb.runCalled = true
|
|
||||||
tb.runHook = h
|
|
||||||
tb.runUi = ui
|
|
||||||
tb.runCache = c
|
|
||||||
return &TestArtifact{id: tb.artifactId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tb *TestBuilder) Cancel() {
|
|
||||||
tb.cancelCalled = true
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testComponentFinder() *ComponentFinder {
|
func testComponentFinder() *ComponentFinder {
|
||||||
builderFactory := func(n string) (Builder, error) { return testBuilder(), nil }
|
builderFactory := func(n string) (Builder, error) { return new(MockBuilder), nil }
|
||||||
ppFactory := func(n string) (PostProcessor, error) { return new(TestPostProcessor), nil }
|
ppFactory := func(n string) (PostProcessor, error) { return new(TestPostProcessor), nil }
|
||||||
provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil }
|
provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil }
|
||||||
return &ComponentFinder{
|
return &ComponentFinder{
|
||||||
|
@ -97,7 +97,7 @@ func TestEnvironment_NilComponents(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironment_Builder(t *testing.T) {
|
func TestEnvironment_Builder(t *testing.T) {
|
||||||
builder := &TestBuilder{}
|
builder := &MockBuilder{}
|
||||||
builders := make(map[string]Builder)
|
builders := make(map[string]Builder)
|
||||||
builders["foo"] = builder
|
builders["foo"] = builder
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func testTemplateComponentFinder() *ComponentFinder {
|
func testTemplateComponentFinder() *ComponentFinder {
|
||||||
builder := testBuilder()
|
builder := new(MockBuilder)
|
||||||
pp := new(TestPostProcessor)
|
pp := new(TestPostProcessor)
|
||||||
provisioner := &MockProvisioner{}
|
provisioner := &MockProvisioner{}
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ func TestTemplate_Build(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder := testBuilder()
|
builder := new(MockBuilder)
|
||||||
builderMap := map[string]Builder{
|
builderMap := map[string]Builder{
|
||||||
"test-builder": builder,
|
"test-builder": builder,
|
||||||
}
|
}
|
||||||
|
@ -1194,7 +1194,7 @@ func TestTemplate_Build_ProvisionerOverride(t *testing.T) {
|
||||||
t.Fatalf("bad raw: %#v", RawConfig)
|
t.Fatalf("bad raw: %#v", RawConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder := testBuilder()
|
builder := new(MockBuilder)
|
||||||
builderMap := map[string]Builder{
|
builderMap := map[string]Builder{
|
||||||
"test-builder": builder,
|
"test-builder": builder,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue