hcl2: allow to optionnaly name provisioners and post-processors
This commit is contained in:
parent
b5075a35c0
commit
2d1a67c6cb
|
@ -10,6 +10,6 @@ type Decodable interface {
|
|||
ConfigSpec() hcldec.ObjectSpec
|
||||
}
|
||||
|
||||
func decodeHCL2Spec(block *hcl.Block, ctx *hcl.EvalContext, dec Decodable) (cty.Value, hcl.Diagnostics) {
|
||||
return hcldec.Decode(block.Body, dec.ConfigSpec(), ctx)
|
||||
func decodeHCL2Spec(body hcl.Body, ctx *hcl.EvalContext, dec Decodable) (cty.Value, hcl.Diagnostics) {
|
||||
return hcldec.Decode(body, dec.ConfigSpec(), ctx)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ build {
|
|||
]
|
||||
|
||||
provisioner "shell" {
|
||||
name = "provisioner that does something"
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
|
@ -83,6 +84,46 @@ build {
|
|||
}
|
||||
}
|
||||
|
||||
post-processor "amazon-import" {
|
||||
name = "something"
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
|
||||
nested {
|
||||
string = "string"
|
||||
int = 42
|
||||
int64 = 43
|
||||
bool = true
|
||||
trilean = true
|
||||
duration = "10s"
|
||||
map_string_string {
|
||||
a = "b"
|
||||
c = "d"
|
||||
}
|
||||
slice_string = [
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
]
|
||||
}
|
||||
|
||||
nested_slice {
|
||||
}
|
||||
}
|
||||
|
||||
post-processor "amazon-import" {
|
||||
string = "string"
|
||||
int = 42
|
||||
|
|
|
@ -78,7 +78,7 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
|
|||
}
|
||||
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
|
||||
case buildPostProcessorLabel:
|
||||
pp, moreDiags := p.decodePostProcessorGroup(block)
|
||||
pp, moreDiags := p.decodePostProcessor(block)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
|
|
|
@ -4,27 +4,43 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/gohcl"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
// PostProcessorBlock represents a parsed PostProcessorBlock
|
||||
type PostProcessorBlock struct {
|
||||
PType string
|
||||
block *hcl.Block
|
||||
PName string
|
||||
|
||||
HCL2Ref
|
||||
}
|
||||
|
||||
func (p *Parser) decodePostProcessorGroup(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) {
|
||||
postProcessor := &PostProcessorBlock{
|
||||
PType: block.Labels[0],
|
||||
block: block,
|
||||
func (p *PostProcessorBlock) String() string {
|
||||
return fmt.Sprintf(buildPostProcessorLabel+"-block %q %q", p.PType, p.PName)
|
||||
}
|
||||
|
||||
func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) {
|
||||
var b struct {
|
||||
Name string `hcl:"name,optional"`
|
||||
Rest hcl.Body `hcl:",remain"`
|
||||
}
|
||||
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
postProcessor := &PostProcessorBlock{
|
||||
PType: block.Labels[0],
|
||||
PName: b.Name,
|
||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||
}
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
if !p.PostProcessorsSchemas.Has(postProcessor.PType) {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Unknown " + buildPostProcessorLabel + " type " + postProcessor.PType,
|
||||
Summary: fmt.Sprintf("Unknown "+buildPostProcessorLabel+" type %q", postProcessor.PType),
|
||||
Subject: block.LabelRanges[0].Ptr(),
|
||||
Detail: fmt.Sprintf("known provisioners: %v", p.ProvisionersSchemas.List()),
|
||||
Detail: fmt.Sprintf("known "+buildPostProcessorLabel+"s: %v", p.PostProcessorsSchemas.List()),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
return nil, diags
|
||||
|
@ -39,21 +55,21 @@ func (p *Parser) StartPostProcessor(pp *PostProcessorBlock) (packer.PostProcesso
|
|||
postProcessor, err := p.PostProcessorsSchemas.Start(pp.PType)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Failed loading " + pp.block.Type,
|
||||
Subject: pp.block.LabelRanges[0].Ptr(),
|
||||
Summary: fmt.Sprintf("Failed loading %s", pp.PType),
|
||||
Subject: pp.DefRange.Ptr(),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.block, nil, postProcessor)
|
||||
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, nil, postProcessor)
|
||||
diags = append(diags, moreDiags...)
|
||||
err = postProcessor.Configure(flatProvisinerCfg)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Failed preparing " + pp.block.Type,
|
||||
Summary: fmt.Sprintf("Failed preparing %s", pp),
|
||||
Detail: err.Error(),
|
||||
Subject: pp.block.DefRange.Ptr(),
|
||||
Subject: pp.DefRange.Ptr(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package hcl2template
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/gohcl"
|
||||
"github.com/hashicorp/packer/helper/common"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
@ -10,21 +12,34 @@ import (
|
|||
// ProvisionerBlock represents a parsed provisioner
|
||||
type ProvisionerBlock struct {
|
||||
PType string
|
||||
block *hcl.Block
|
||||
PName string
|
||||
HCL2Ref
|
||||
}
|
||||
|
||||
func (p *ProvisionerBlock) String() string {
|
||||
return fmt.Sprintf(buildProvisionerLabel+"-block %q %q", p.PType, p.PName)
|
||||
}
|
||||
|
||||
func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Diagnostics) {
|
||||
provisioner := &ProvisionerBlock{
|
||||
PType: block.Labels[0],
|
||||
block: block,
|
||||
var b struct {
|
||||
Name string `hcl:"name,optional"`
|
||||
Rest hcl.Body `hcl:",remain"`
|
||||
}
|
||||
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
provisioner := &ProvisionerBlock{
|
||||
PType: block.Labels[0],
|
||||
PName: b.Name,
|
||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||
}
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
if !p.ProvisionersSchemas.Has(provisioner.PType) {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Unknown " + buildProvisionerLabel + " type " + provisioner.PType,
|
||||
Summary: fmt.Sprintf("Unknown "+buildProvisionerLabel+" type %q", provisioner.PType),
|
||||
Subject: block.LabelRanges[0].Ptr(),
|
||||
Detail: fmt.Sprintf("known provisioners: %v", p.ProvisionersSchemas.List()),
|
||||
Detail: fmt.Sprintf("known "+buildProvisionerLabel+"s: %v", p.ProvisionersSchemas.List()),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
return nil, diags
|
||||
|
@ -38,13 +53,13 @@ func (p *Parser) StartProvisioner(pb *ProvisionerBlock, generatedVars []string)
|
|||
provisioner, err := p.ProvisionersSchemas.Start(pb.PType)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Failed loading " + pb.block.Type,
|
||||
Subject: pb.block.LabelRanges[0].Ptr(),
|
||||
Summary: fmt.Sprintf("failed loading %s", pb.PType),
|
||||
Subject: pb.HCL2Ref.LabelsRanges[0].Ptr(),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
flatProvisionerCfg, moreDiags := decodeHCL2Spec(pb.block, nil, provisioner)
|
||||
flatProvisionerCfg, moreDiags := decodeHCL2Spec(pb.HCL2Ref.Rest, nil, provisioner)
|
||||
diags = append(diags, moreDiags...)
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
|
@ -71,9 +86,9 @@ func (p *Parser) StartProvisioner(pb *ProvisionerBlock, generatedVars []string)
|
|||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Failed preparing " + pb.block.Type,
|
||||
Summary: fmt.Sprintf("Failed preparing %s", pb),
|
||||
Detail: err.Error(),
|
||||
Subject: pb.block.DefRange.Ptr(),
|
||||
Subject: pb.HCL2Ref.DefRange.Ptr(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
|
|
|
@ -7,8 +7,19 @@ import (
|
|||
// reference to the source definition in configuration text file
|
||||
type HCL2Ref struct {
|
||||
// reference to the source definition in configuration text file
|
||||
DeclRange hcl.Range
|
||||
DefRange hcl.Range
|
||||
TypeRange hcl.Range
|
||||
LabelsRanges []hcl.Range
|
||||
|
||||
// remainder of unparsed body
|
||||
Remain hcl.Body
|
||||
Rest hcl.Body
|
||||
}
|
||||
|
||||
func newHCL2Ref(block *hcl.Block, rest hcl.Body) HCL2Ref {
|
||||
return HCL2Ref{
|
||||
Rest: rest,
|
||||
DefRange: block.DefRange,
|
||||
TypeRange: block.TypeRange,
|
||||
LabelsRanges: block.LabelRanges,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ func (p *Parser) CoreBuildProvisioners(blocks []*ProvisionerBlock, generatedVars
|
|||
}
|
||||
res = append(res, packer.CoreBuildProvisioner{
|
||||
PType: pb.PType,
|
||||
PName: pb.PName,
|
||||
Provisioner: provisioner,
|
||||
})
|
||||
}
|
||||
|
@ -34,15 +35,16 @@ func (p *Parser) CoreBuildProvisioners(blocks []*ProvisionerBlock, generatedVars
|
|||
func (p *Parser) CoreBuildPostProcessors(blocks []*PostProcessorBlock) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
|
||||
var diags hcl.Diagnostics
|
||||
res := []packer.CoreBuildPostProcessor{}
|
||||
for _, pp := range blocks {
|
||||
postProcessor, moreDiags := p.StartPostProcessor(pp)
|
||||
for _, ppb := range blocks {
|
||||
postProcessor, moreDiags := p.StartPostProcessor(ppb)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
}
|
||||
res = append(res, packer.CoreBuildPostProcessor{
|
||||
PostProcessor: postProcessor,
|
||||
PType: pp.PType,
|
||||
PName: ppb.PName,
|
||||
PType: ppb.PType,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,7 @@ func (p *Parser) getBuilds(cfg *PackerConfig) ([]packer.Build, hcl.Diagnostics)
|
|||
if !found {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Unknown " + sourceLabel + " " + from.String(),
|
||||
Subject: build.HCL2Ref.DeclRange.Ptr(),
|
||||
Subject: build.HCL2Ref.DefRange.Ptr(),
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
continue
|
||||
|
|
|
@ -26,11 +26,20 @@ func TestParser_complete(t *testing.T) {
|
|||
&BuildBlock{
|
||||
Froms: []SourceRef{refVBIsoUbuntu1204},
|
||||
ProvisionerBlocks: []*ProvisionerBlock{
|
||||
{PType: "shell"},
|
||||
{
|
||||
PType: "shell",
|
||||
PName: "provisioner that does something",
|
||||
},
|
||||
{PType: "file"},
|
||||
},
|
||||
PostProcessors: []*PostProcessorBlock{
|
||||
{PType: "amazon-import"},
|
||||
{
|
||||
PType: "amazon-import",
|
||||
PName: "something",
|
||||
},
|
||||
{
|
||||
PType: "amazon-import",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -41,12 +50,24 @@ func TestParser_complete(t *testing.T) {
|
|||
Type: "virtualbox-iso",
|
||||
Builder: basicMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{
|
||||
{PType: "shell", Provisioner: basicMockProvisioner},
|
||||
{
|
||||
PType: "shell",
|
||||
PName: "provisioner that does something",
|
||||
Provisioner: basicMockProvisioner,
|
||||
},
|
||||
{PType: "file", Provisioner: basicMockProvisioner},
|
||||
},
|
||||
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
||||
{
|
||||
{PType: "amazon-import", PostProcessor: basicMockPostProcessor},
|
||||
{
|
||||
PType: "amazon-import",
|
||||
PName: "something",
|
||||
PostProcessor: basicMockPostProcessor,
|
||||
},
|
||||
{
|
||||
PType: "amazon-import",
|
||||
PostProcessor: basicMockPostProcessor,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -52,7 +52,7 @@ func (p *Parser) StartBuilder(source *Source) (packer.Builder, hcl.Diagnostics,
|
|||
return builder, diags, nil
|
||||
}
|
||||
|
||||
decoded, moreDiags := decodeHCL2Spec(source.block, nil, builder)
|
||||
decoded, moreDiags := decodeHCL2Spec(source.block.Body, nil, builder)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
return nil, diags, nil
|
||||
|
|
|
@ -118,6 +118,7 @@ type CoreBuildPostProcessor struct {
|
|||
// the provisioner within the build.
|
||||
type CoreBuildProvisioner struct {
|
||||
PType string
|
||||
PName string
|
||||
Provisioner Provisioner
|
||||
config []interface{}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue