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
|
ConfigSpec() hcldec.ObjectSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeHCL2Spec(block *hcl.Block, ctx *hcl.EvalContext, dec Decodable) (cty.Value, hcl.Diagnostics) {
|
func decodeHCL2Spec(body hcl.Body, ctx *hcl.EvalContext, dec Decodable) (cty.Value, hcl.Diagnostics) {
|
||||||
return hcldec.Decode(block.Body, dec.ConfigSpec(), ctx)
|
return hcldec.Decode(body, dec.ConfigSpec(), ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ build {
|
||||||
]
|
]
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
|
name = "provisioner that does something"
|
||||||
string = "string"
|
string = "string"
|
||||||
int = 42
|
int = 42
|
||||||
int64 = 43
|
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" {
|
post-processor "amazon-import" {
|
||||||
string = "string"
|
string = "string"
|
||||||
int = 42
|
int = 42
|
||||||
|
|
|
@ -78,7 +78,7 @@ func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnosti
|
||||||
}
|
}
|
||||||
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
|
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
|
||||||
case buildPostProcessorLabel:
|
case buildPostProcessorLabel:
|
||||||
pp, moreDiags := p.decodePostProcessorGroup(block)
|
pp, moreDiags := p.decodePostProcessor(block)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -4,27 +4,43 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PostProcessorBlock represents a parsed PostProcessorBlock
|
// PostProcessorBlock represents a parsed PostProcessorBlock
|
||||||
type PostProcessorBlock struct {
|
type PostProcessorBlock struct {
|
||||||
PType string
|
PType string
|
||||||
block *hcl.Block
|
PName string
|
||||||
|
|
||||||
|
HCL2Ref
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) decodePostProcessorGroup(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) {
|
|
||||||
postProcessor := &PostProcessorBlock{
|
postProcessor := &PostProcessorBlock{
|
||||||
PType: block.Labels[0],
|
PType: block.Labels[0],
|
||||||
block: block,
|
PName: b.Name,
|
||||||
|
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||||
}
|
}
|
||||||
var diags hcl.Diagnostics
|
|
||||||
|
|
||||||
if !p.PostProcessorsSchemas.Has(postProcessor.PType) {
|
if !p.PostProcessorsSchemas.Has(postProcessor.PType) {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
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(),
|
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,
|
Severity: hcl.DiagError,
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
|
@ -39,21 +55,21 @@ func (p *Parser) StartPostProcessor(pp *PostProcessorBlock) (packer.PostProcesso
|
||||||
postProcessor, err := p.PostProcessorsSchemas.Start(pp.PType)
|
postProcessor, err := p.PostProcessorsSchemas.Start(pp.PType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Summary: "Failed loading " + pp.block.Type,
|
Summary: fmt.Sprintf("Failed loading %s", pp.PType),
|
||||||
Subject: pp.block.LabelRanges[0].Ptr(),
|
Subject: pp.DefRange.Ptr(),
|
||||||
Detail: err.Error(),
|
Detail: err.Error(),
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.block, nil, postProcessor)
|
flatProvisinerCfg, moreDiags := decodeHCL2Spec(pp.Rest, nil, postProcessor)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
err = postProcessor.Configure(flatProvisinerCfg)
|
err = postProcessor.Configure(flatProvisinerCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Failed preparing " + pp.block.Type,
|
Summary: fmt.Sprintf("Failed preparing %s", pp),
|
||||||
Detail: err.Error(),
|
Detail: err.Error(),
|
||||||
Subject: pp.block.DefRange.Ptr(),
|
Subject: pp.DefRange.Ptr(),
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package hcl2template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
"github.com/hashicorp/packer/helper/common"
|
"github.com/hashicorp/packer/helper/common"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
@ -10,21 +12,34 @@ import (
|
||||||
// ProvisionerBlock represents a parsed provisioner
|
// ProvisionerBlock represents a parsed provisioner
|
||||||
type ProvisionerBlock struct {
|
type ProvisionerBlock struct {
|
||||||
PType string
|
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) {
|
func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, 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
|
||||||
|
}
|
||||||
provisioner := &ProvisionerBlock{
|
provisioner := &ProvisionerBlock{
|
||||||
PType: block.Labels[0],
|
PType: block.Labels[0],
|
||||||
block: block,
|
PName: b.Name,
|
||||||
|
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||||
}
|
}
|
||||||
var diags hcl.Diagnostics
|
|
||||||
|
|
||||||
if !p.ProvisionersSchemas.Has(provisioner.PType) {
|
if !p.ProvisionersSchemas.Has(provisioner.PType) {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
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(),
|
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,
|
Severity: hcl.DiagError,
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
|
@ -38,13 +53,13 @@ func (p *Parser) StartProvisioner(pb *ProvisionerBlock, generatedVars []string)
|
||||||
provisioner, err := p.ProvisionersSchemas.Start(pb.PType)
|
provisioner, err := p.ProvisionersSchemas.Start(pb.PType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Summary: "Failed loading " + pb.block.Type,
|
Summary: fmt.Sprintf("failed loading %s", pb.PType),
|
||||||
Subject: pb.block.LabelRanges[0].Ptr(),
|
Subject: pb.HCL2Ref.LabelsRanges[0].Ptr(),
|
||||||
Detail: err.Error(),
|
Detail: err.Error(),
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
flatProvisionerCfg, moreDiags := decodeHCL2Spec(pb.block, nil, provisioner)
|
flatProvisionerCfg, moreDiags := decodeHCL2Spec(pb.HCL2Ref.Rest, nil, provisioner)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
return nil, diags
|
return nil, diags
|
||||||
|
@ -71,9 +86,9 @@ func (p *Parser) StartProvisioner(pb *ProvisionerBlock, generatedVars []string)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Failed preparing " + pb.block.Type,
|
Summary: fmt.Sprintf("Failed preparing %s", pb),
|
||||||
Detail: err.Error(),
|
Detail: err.Error(),
|
||||||
Subject: pb.block.DefRange.Ptr(),
|
Subject: pb.HCL2Ref.DefRange.Ptr(),
|
||||||
})
|
})
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,19 @@ import (
|
||||||
// reference to the source definition in configuration text file
|
// reference to the source definition in configuration text file
|
||||||
type HCL2Ref struct {
|
type HCL2Ref struct {
|
||||||
// reference to the source definition in configuration text file
|
// 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
|
// 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{
|
res = append(res, packer.CoreBuildProvisioner{
|
||||||
PType: pb.PType,
|
PType: pb.PType,
|
||||||
|
PName: pb.PName,
|
||||||
Provisioner: provisioner,
|
Provisioner: provisioner,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -34,15 +35,16 @@ func (p *Parser) CoreBuildProvisioners(blocks []*ProvisionerBlock, generatedVars
|
||||||
func (p *Parser) CoreBuildPostProcessors(blocks []*PostProcessorBlock) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
|
func (p *Parser) CoreBuildPostProcessors(blocks []*PostProcessorBlock) ([]packer.CoreBuildPostProcessor, hcl.Diagnostics) {
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
res := []packer.CoreBuildPostProcessor{}
|
res := []packer.CoreBuildPostProcessor{}
|
||||||
for _, pp := range blocks {
|
for _, ppb := range blocks {
|
||||||
postProcessor, moreDiags := p.StartPostProcessor(pp)
|
postProcessor, moreDiags := p.StartPostProcessor(ppb)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res = append(res, packer.CoreBuildPostProcessor{
|
res = append(res, packer.CoreBuildPostProcessor{
|
||||||
PostProcessor: postProcessor,
|
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 {
|
if !found {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Summary: "Unknown " + sourceLabel + " " + from.String(),
|
Summary: "Unknown " + sourceLabel + " " + from.String(),
|
||||||
Subject: build.HCL2Ref.DeclRange.Ptr(),
|
Subject: build.HCL2Ref.DefRange.Ptr(),
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -26,11 +26,20 @@ func TestParser_complete(t *testing.T) {
|
||||||
&BuildBlock{
|
&BuildBlock{
|
||||||
Froms: []SourceRef{refVBIsoUbuntu1204},
|
Froms: []SourceRef{refVBIsoUbuntu1204},
|
||||||
ProvisionerBlocks: []*ProvisionerBlock{
|
ProvisionerBlocks: []*ProvisionerBlock{
|
||||||
{PType: "shell"},
|
{
|
||||||
|
PType: "shell",
|
||||||
|
PName: "provisioner that does something",
|
||||||
|
},
|
||||||
{PType: "file"},
|
{PType: "file"},
|
||||||
},
|
},
|
||||||
PostProcessors: []*PostProcessorBlock{
|
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",
|
Type: "virtualbox-iso",
|
||||||
Builder: basicMockBuilder,
|
Builder: basicMockBuilder,
|
||||||
Provisioners: []packer.CoreBuildProvisioner{
|
Provisioners: []packer.CoreBuildProvisioner{
|
||||||
{PType: "shell", Provisioner: basicMockProvisioner},
|
{
|
||||||
|
PType: "shell",
|
||||||
|
PName: "provisioner that does something",
|
||||||
|
Provisioner: basicMockProvisioner,
|
||||||
|
},
|
||||||
{PType: "file", Provisioner: basicMockProvisioner},
|
{PType: "file", Provisioner: basicMockProvisioner},
|
||||||
},
|
},
|
||||||
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
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
|
return builder, diags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
decoded, moreDiags := decodeHCL2Spec(source.block, nil, builder)
|
decoded, moreDiags := decodeHCL2Spec(source.block.Body, nil, builder)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
return nil, diags, nil
|
return nil, diags, nil
|
||||||
|
|
|
@ -118,6 +118,7 @@ type CoreBuildPostProcessor struct {
|
||||||
// the provisioner within the build.
|
// the provisioner within the build.
|
||||||
type CoreBuildProvisioner struct {
|
type CoreBuildProvisioner struct {
|
||||||
PType string
|
PType string
|
||||||
|
PName string
|
||||||
Provisioner Provisioner
|
Provisioner Provisioner
|
||||||
config []interface{}
|
config []interface{}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue