add hcl2 post processor type that reprepares itself

This commit is contained in:
Adrien Delorme 2020-07-06 10:32:39 +02:00
parent db6c3adbba
commit 39261f3671
6 changed files with 122 additions and 33 deletions

View File

@ -130,6 +130,7 @@ func testParse(t *testing.T, tests []parseTest) {
packer.CoreBuildPostProcessor{},
null.Builder{},
HCL2Provisioner{},
HCL2PostProcessor{},
),
); diff != "" {
t.Fatalf("Parser.getBuilds() wrong packer builds. %s", diff)

View File

@ -74,9 +74,13 @@ func (cfg *PackerConfig) startPostProcessor(source SourceBlock, pp *PostProcesso
})
return nil, diags
}
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, ectx, postProcessor)
diags = append(diags, moreDiags...)
err = postProcessor.Configure(source.builderVariables(), flatProvisinerCfg)
hclPostProcessor := &HCL2PostProcessor{
PostProcessor: postProcessor,
postProcessorBlock: pp,
evalContext: ectx,
builderVariables: source.builderVariables(),
}
err = hclPostProcessor.HCL2Prepare(generatedVars)
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
@ -86,5 +90,5 @@ func (cfg *PackerConfig) startPostProcessor(source SourceBlock, pp *PostProcesso
})
return nil, diags
}
return postProcessor, diags
return hclPostProcessor, diags
}

View File

@ -144,13 +144,13 @@ func (cfg *PackerConfig) startProvisioner(source SourceBlock, pb *ProvisionerBlo
})
return nil, diags
}
p := &HCL2Provisioner{
hclProvisioner := &HCL2Provisioner{
Provisioner: provisioner,
provisionerBlock: pb,
evalContext: ectx,
builderVariables: source.builderVariables(),
}
err = p.HCL2Prepare(generatedVars)
err = hclProvisioner.HCL2Prepare(generatedVars)
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
@ -160,5 +160,5 @@ func (cfg *PackerConfig) startProvisioner(source SourceBlock, pb *ProvisionerBlo
})
return nil, diags
}
return p, diags
return hclProvisioner, diags
}

View File

@ -171,19 +171,23 @@ func TestParse_build(t *testing.T) {
{
{
PType: "amazon-import",
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
PostProcessor: &HCL2PostProcessor{
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
},
},
},
},
{
PType: "manifest",
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
PostProcessor: &HCL2PostProcessor{
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
},
},
},
},
@ -199,19 +203,23 @@ func TestParse_build(t *testing.T) {
{
{
PType: "manifest",
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
PostProcessor: &HCL2PostProcessor{
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
},
},
},
},
{
PType: "amazon-import",
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
PostProcessor: &HCL2PostProcessor{
PostProcessor: &MockPostProcessor{
Config: MockConfig{
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
NestedSlice: []NestedMockConfig{},
},
},
},
},

View File

@ -0,0 +1,68 @@
package hcl2template
import (
"context"
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/packer"
"github.com/zclconf/go-cty/cty"
)
type HCL2PostProcessor struct {
PostProcessor packer.PostProcessor
postProcessorBlock *PostProcessorBlock
evalContext *hcl.EvalContext
builderVariables map[string]string
}
func (p *HCL2PostProcessor) ConfigSpec() hcldec.ObjectSpec {
return p.PostProcessor.ConfigSpec()
}
func (p *HCL2PostProcessor) HCL2Prepare(buildVars map[string]interface{}) error {
var diags hcl.Diagnostics
ectx := p.evalContext
if len(buildVars) > 0 {
ectx = p.evalContext.NewChild()
buildValues := map[string]cty.Value{}
for k, v := range buildVars {
switch v := v.(type) {
case string:
buildValues[k] = cty.StringVal(v)
default:
return fmt.Errorf("unhandled builvar type: %T", v)
}
}
ectx.Variables = map[string]cty.Value{
buildAccessor: cty.ObjectVal(buildValues),
}
}
flatPostProcessorCfg, moreDiags := decodeHCL2Spec(p.postProcessorBlock.HCL2Ref.Rest, ectx, p.PostProcessor)
diags = append(diags, moreDiags...)
if diags.HasErrors() {
return diags
}
return p.PostProcessor.Configure(p.builderVariables, flatPostProcessorCfg)
}
func (p *HCL2PostProcessor) Configure(args ...interface{}) error {
return p.PostProcessor.Configure(args...)
}
func (p *HCL2PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) {
generatedData := make(map[string]interface{})
if artifactStateData, ok := artifact.State("generated_data").(map[interface{}]interface{}); ok {
for k, v := range artifactStateData {
generatedData[k.(string)] = v
}
}
err := p.HCL2Prepare(generatedData)
if err != nil {
return nil, false, false, err
}
return p.PostProcessor.PostProcess(ctx, ui, artifact)
}

View File

@ -126,14 +126,18 @@ func TestParser_complete(t *testing.T) {
PostProcessors: [][]packer.CoreBuildPostProcessor{
{
{
PType: "amazon-import",
PName: "something",
PostProcessor: basicMockPostProcessor,
PType: "amazon-import",
PName: "something",
PostProcessor: &HCL2PostProcessor{
PostProcessor: basicMockPostProcessor,
},
KeepInputArtifact: pTrue,
},
{
PType: "amazon-import",
PostProcessor: basicMockPostProcessor,
PType: "amazon-import",
PostProcessor: &HCL2PostProcessor{
PostProcessor: basicMockPostProcessor,
},
},
},
},
@ -169,14 +173,18 @@ func TestParser_complete(t *testing.T) {
PostProcessors: [][]packer.CoreBuildPostProcessor{
{
{
PType: "amazon-import",
PName: "something",
PostProcessor: basicMockPostProcessor,
PType: "amazon-import",
PName: "something",
PostProcessor: &HCL2PostProcessor{
PostProcessor: basicMockPostProcessor,
},
KeepInputArtifact: pTrue,
},
{
PType: "amazon-import",
PostProcessor: basicMockPostProcessor,
PType: "amazon-import",
PostProcessor: &HCL2PostProcessor{
PostProcessor: basicMockPostProcessor,
},
},
},
},