packer: post-processors
This commit is contained in:
parent
85e615bbe2
commit
26c7ac2d90
|
@ -19,7 +19,7 @@ func testBuild() *coreBuild {
|
|||
},
|
||||
postProcessors: [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp"}, "testPP", make(map[string]interface{}), true},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp"}, "testPP", make(map[string]interface{}), true},
|
||||
},
|
||||
},
|
||||
variables: make(map[string]string),
|
||||
|
@ -66,12 +66,12 @@ func TestBuild_Prepare(t *testing.T) {
|
|||
}
|
||||
|
||||
corePP := build.postProcessors[0][0]
|
||||
pp := corePP.processor.(*TestPostProcessor)
|
||||
if !pp.configCalled {
|
||||
pp := corePP.processor.(*MockPostProcessor)
|
||||
if !pp.ConfigureCalled {
|
||||
t.Fatal("should be called")
|
||||
}
|
||||
if !reflect.DeepEqual(pp.configVal, []interface{}{make(map[string]interface{}), packerConfig}) {
|
||||
t.Fatalf("bad: %#v", pp.configVal)
|
||||
if !reflect.DeepEqual(pp.ConfigureConfigs, []interface{}{make(map[string]interface{}), packerConfig}) {
|
||||
t.Fatalf("bad: %#v", pp.ConfigureConfigs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,8 +208,8 @@ func TestBuild_Run(t *testing.T) {
|
|||
}
|
||||
|
||||
// Verify post-processor was run
|
||||
pp := build.postProcessors[0][0].processor.(*TestPostProcessor)
|
||||
if !pp.ppCalled {
|
||||
pp := build.postProcessors[0][0].processor.(*MockPostProcessor)
|
||||
if !pp.PostProcessCalled {
|
||||
t.Fatal("should be called")
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ func TestBuild_Run_Artifacts(t *testing.T) {
|
|||
build = testBuild()
|
||||
build.postProcessors = [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp"}, "pp", make(map[string]interface{}), false},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -269,10 +269,10 @@ func TestBuild_Run_Artifacts(t *testing.T) {
|
|||
build = testBuild()
|
||||
build.postProcessors = [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp1"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1"}, "pp", make(map[string]interface{}), false},
|
||||
},
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp2"}, "pp", make(map[string]interface{}), true},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2"}, "pp", make(map[string]interface{}), true},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -297,12 +297,12 @@ func TestBuild_Run_Artifacts(t *testing.T) {
|
|||
build = testBuild()
|
||||
build.postProcessors = [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp1a"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp1b"}, "pp", make(map[string]interface{}), true},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1a"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp1b"}, "pp", make(map[string]interface{}), true},
|
||||
},
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp2a"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&TestPostProcessor{artifactId: "pp2b"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2a"}, "pp", make(map[string]interface{}), false},
|
||||
coreBuildPostProcessor{&MockPostProcessor{ArtifactId: "pp2b"}, "pp", make(map[string]interface{}), false},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ func TestBuild_Run_Artifacts(t *testing.T) {
|
|||
build.postProcessors = [][]coreBuildPostProcessor{
|
||||
[]coreBuildPostProcessor{
|
||||
coreBuildPostProcessor{
|
||||
&TestPostProcessor{artifactId: "pp", keep: true}, "pp", make(map[string]interface{}), false,
|
||||
&MockPostProcessor{ArtifactId: "pp", Keep: true}, "pp", make(map[string]interface{}), false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -161,13 +161,54 @@ func (c *Core) Build(n string) (Build, error) {
|
|||
})
|
||||
}
|
||||
|
||||
// Setup the post-processors
|
||||
postProcessors := make([][]coreBuildPostProcessor, 0, len(c.template.PostProcessors))
|
||||
for _, rawPs := range c.template.PostProcessors {
|
||||
current := make([]coreBuildPostProcessor, 0, len(rawPs))
|
||||
for _, rawP := range rawPs {
|
||||
// If we skip, ignore
|
||||
if rawP.Skip(rawName) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the post-processor
|
||||
postProcessor, err := c.components.PostProcessor(rawP.Type)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"error initializing post-processor '%s': %s",
|
||||
rawP.Type, err)
|
||||
}
|
||||
if postProcessor == nil {
|
||||
return nil, fmt.Errorf(
|
||||
"post-processor type not found: %s", rawP.Type)
|
||||
}
|
||||
|
||||
current = append(current, coreBuildPostProcessor{
|
||||
processor: postProcessor,
|
||||
processorType: rawP.Type,
|
||||
config: rawP.Config,
|
||||
keepInputArtifact: rawP.KeepInputArtifact,
|
||||
})
|
||||
}
|
||||
|
||||
// If we have no post-processors in this chain, just continue.
|
||||
if len(current) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
postProcessors = append(postProcessors, current)
|
||||
}
|
||||
|
||||
// TODO hooks one day
|
||||
|
||||
return &coreBuild{
|
||||
name: n,
|
||||
builder: builder,
|
||||
builderConfig: configBuilder.Config,
|
||||
builderType: configBuilder.Type,
|
||||
provisioners: provisioners,
|
||||
variables: c.variables,
|
||||
name: n,
|
||||
builder: builder,
|
||||
builderConfig: configBuilder.Config,
|
||||
builderType: configBuilder.Type,
|
||||
postProcessors: postProcessors,
|
||||
provisioners: provisioners,
|
||||
variables: c.variables,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,42 @@ func TestCoreBuild_provSkipInclude(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCoreBuild_postProcess(t *testing.T) {
|
||||
config := TestCoreConfig(t)
|
||||
testCoreTemplate(t, config, fixtureDir("build-pp.json"))
|
||||
b := TestBuilder(t, config, "test")
|
||||
p := TestPostProcessor(t, config, "test")
|
||||
core := TestCore(t, config)
|
||||
ui := TestUi(t)
|
||||
|
||||
b.ArtifactId = "hello"
|
||||
p.ArtifactId = "goodbye"
|
||||
|
||||
build, err := core.Build("test")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if _, err := build.Prepare(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
artifact, err := build.Run(ui, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if len(artifact) != 1 {
|
||||
t.Fatalf("bad: %#v", artifact)
|
||||
}
|
||||
|
||||
if artifact[0].Id() != p.ArtifactId {
|
||||
t.Fatalf("bad: %s", artifact[0].Id())
|
||||
}
|
||||
if p.PostProcessArtifact.Id() != b.ArtifactId {
|
||||
t.Fatalf("bad: %s", p.PostProcessArtifact.Id())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreValidate(t *testing.T) {
|
||||
cases := []struct {
|
||||
File string
|
||||
|
@ -276,7 +312,7 @@ func TestCoreValidate(t *testing.T) {
|
|||
|
||||
func testComponentFinder() *ComponentFinder {
|
||||
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(MockPostProcessor), nil }
|
||||
provFactory := func(n string) (Provisioner, error) { return new(MockProvisioner), nil }
|
||||
return &ComponentFinder{
|
||||
Builder: builderFactory,
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package packer
|
||||
|
||||
// MockPostProcessor is an implementation of PostProcessor that can be
|
||||
// used for tests.
|
||||
type MockPostProcessor struct {
|
||||
ArtifactId string
|
||||
Keep bool
|
||||
Error error
|
||||
|
||||
ConfigureCalled bool
|
||||
ConfigureConfigs []interface{}
|
||||
ConfigureError error
|
||||
|
||||
PostProcessCalled bool
|
||||
PostProcessArtifact Artifact
|
||||
PostProcessUi Ui
|
||||
}
|
||||
|
||||
func (t *MockPostProcessor) Configure(configs ...interface{}) error {
|
||||
t.ConfigureCalled = true
|
||||
t.ConfigureConfigs = configs
|
||||
return t.ConfigureError
|
||||
}
|
||||
|
||||
func (t *MockPostProcessor) PostProcess(ui Ui, a Artifact) (Artifact, bool, error) {
|
||||
t.PostProcessCalled = true
|
||||
t.PostProcessArtifact = a
|
||||
t.PostProcessUi = ui
|
||||
|
||||
return &MockArtifact{
|
||||
IdValue: t.ArtifactId,
|
||||
}, t.Keep, t.Error
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package packer
|
||||
|
||||
type TestPostProcessor struct {
|
||||
artifactId string
|
||||
keep bool
|
||||
configCalled bool
|
||||
configVal []interface{}
|
||||
ppCalled bool
|
||||
ppArtifact Artifact
|
||||
ppUi Ui
|
||||
}
|
||||
|
||||
func (pp *TestPostProcessor) Configure(v ...interface{}) error {
|
||||
pp.configCalled = true
|
||||
pp.configVal = v
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pp *TestPostProcessor) PostProcess(ui Ui, a Artifact) (Artifact, bool, error) {
|
||||
pp.ppCalled = true
|
||||
pp.ppArtifact = a
|
||||
pp.ppUi = ui
|
||||
return &TestArtifact{id: pp.artifactId}, pp.keep, nil
|
||||
}
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
func testTemplateComponentFinder() *ComponentFinder {
|
||||
builder := new(MockBuilder)
|
||||
pp := new(TestPostProcessor)
|
||||
pp := new(MockPostProcessor)
|
||||
provisioner := &MockProvisioner{}
|
||||
|
||||
builderMap := map[string]Builder{
|
||||
|
@ -1018,7 +1018,7 @@ func TestTemplate_Build(t *testing.T) {
|
|||
"test-prov": provisioner,
|
||||
}
|
||||
|
||||
pp := new(TestPostProcessor)
|
||||
pp := new(MockPostProcessor)
|
||||
ppMap := map[string]PostProcessor{
|
||||
"simple": pp,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"builders": [{
|
||||
"type": "test"
|
||||
}],
|
||||
|
||||
"post-processors": ["test"]
|
||||
}
|
|
@ -8,14 +8,6 @@ import (
|
|||
)
|
||||
|
||||
func TestCoreConfig(t *testing.T) *CoreConfig {
|
||||
// Create a UI that is effectively /dev/null everywhere
|
||||
var buf bytes.Buffer
|
||||
ui := &BasicUi{
|
||||
Reader: &buf,
|
||||
Writer: ioutil.Discard,
|
||||
ErrorWriter: ioutil.Discard,
|
||||
}
|
||||
|
||||
// Create some test components
|
||||
components := ComponentFinder{
|
||||
Builder: func(n string) (Builder, error) {
|
||||
|
@ -30,7 +22,7 @@ func TestCoreConfig(t *testing.T) *CoreConfig {
|
|||
return &CoreConfig{
|
||||
Cache: &FileCache{CacheDir: os.TempDir()},
|
||||
Components: components,
|
||||
Ui: ui,
|
||||
Ui: TestUi(t),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +35,15 @@ func TestCore(t *testing.T, c *CoreConfig) *Core {
|
|||
return core
|
||||
}
|
||||
|
||||
func TestUi(t *testing.T) Ui {
|
||||
var buf bytes.Buffer
|
||||
return &BasicUi{
|
||||
Reader: &buf,
|
||||
Writer: ioutil.Discard,
|
||||
ErrorWriter: ioutil.Discard,
|
||||
}
|
||||
}
|
||||
|
||||
// TestBuilder sets the builder with the name n to the component finder
|
||||
// and returns the mock.
|
||||
func TestBuilder(t *testing.T, c *CoreConfig, n string) *MockBuilder {
|
||||
|
@ -74,3 +75,19 @@ func TestProvisioner(t *testing.T, c *CoreConfig, n string) *MockProvisioner {
|
|||
|
||||
return &b
|
||||
}
|
||||
|
||||
// TestPostProcessor sets the prov. with the name n to the component finder
|
||||
// and returns the mock.
|
||||
func TestPostProcessor(t *testing.T, c *CoreConfig, n string) *MockPostProcessor {
|
||||
var b MockPostProcessor
|
||||
|
||||
c.Components.PostProcessor = func(actual string) (PostProcessor, error) {
|
||||
if actual != n {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
return &b
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue