Files
Packer-Cn/hcl2template/types.build.go
T

128 lines
3.4 KiB
Go
Raw Normal View History

2019-10-14 17:02:53 +02:00
package hcl2template
import (
"github.com/hashicorp/hcl/v2"
2019-12-17 11:25:56 +01:00
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
2019-10-14 17:02:53 +02:00
)
const (
buildFromLabel = "from"
2019-12-17 11:25:56 +01:00
buildSourceLabel = "source"
2019-10-14 17:02:53 +02:00
2019-12-17 11:25:56 +01:00
buildProvisionerLabel = "provisioner"
buildPostProcessorLabel = "post-processor"
2019-10-14 17:02:53 +02:00
)
var buildSchema = &hcl.BodySchema{
Blocks: []hcl.BlockHeaderSchema{
2019-12-17 11:25:56 +01:00
{Type: buildFromLabel, LabelNames: []string{"type"}},
{Type: sourceLabel, LabelNames: []string{"reference"}},
2019-12-17 11:25:56 +01:00
{Type: buildProvisionerLabel, LabelNames: []string{"type"}},
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
2019-10-14 17:02:53 +02:00
},
}
// BuildBlock references an HCL 'build' block and it content, for example :
//
// build {
// sources = [
// ...
// ]
// provisioner "" { ... }
// post-processor "" { ... }
// }
2019-12-17 11:25:56 +01:00
type BuildBlock struct {
2020-05-17 22:13:35 -07:00
// Name is a string representing the named build to show in the logs
Name string
// Sources is the list of sources that we want to start in this build block.
Sources []SourceRef
// ProvisionerBlocks references a list of HCL provisioner block that will
// will be ran against the sources.
2019-12-17 11:25:56 +01:00
ProvisionerBlocks []*ProvisionerBlock
2019-10-14 17:02:53 +02:00
// ProvisionerBlocks references a list of HCL post-processors block that
// will be ran against the artifacts from the provisioning steps.
2019-12-17 11:25:56 +01:00
PostProcessors []*PostProcessorBlock
2019-10-14 17:02:53 +02:00
HCL2Ref HCL2Ref
}
2019-12-17 11:25:56 +01:00
type Builds []*BuildBlock
2019-10-14 17:02:53 +02:00
// decodeBuildConfig is called when a 'build' block has been detected. It will
// load the references to the contents of the build block.
2019-12-17 11:25:56 +01:00
func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnostics) {
build := &BuildBlock{}
2019-10-14 17:02:53 +02:00
2019-12-17 11:25:56 +01:00
var b struct {
2020-05-17 22:13:35 -07:00
Name string `hcl:"name,optional"`
FromSources []string `hcl:"sources,optional"`
2019-12-17 11:25:56 +01:00
Config hcl.Body `hcl:",remain"`
}
diags := gohcl.DecodeBody(block.Body, nil, &b)
2020-02-17 17:15:52 +01:00
if diags.HasErrors() {
return nil, diags
}
2019-12-17 11:25:56 +01:00
2020-05-17 22:13:35 -07:00
build.Name = b.Name
2019-12-17 11:25:56 +01:00
for _, buildFrom := range b.FromSources {
ref := sourceRefFromString(buildFrom)
2020-01-06 17:10:12 +01:00
if ref == NoSource ||
!hclsyntax.ValidIdentifier(ref.Type) ||
2019-12-17 11:25:56 +01:00
!hclsyntax.ValidIdentifier(ref.Name) {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid " + sourceLabel + " reference",
2020-01-06 17:10:12 +01:00
Detail: "A " + sourceLabel + " type is made of three parts that are" +
"split by a dot `.`; each part must start with a letter and " +
2019-12-17 11:25:56 +01:00
"may contain only letters, digits, underscores, and dashes." +
"A valid source reference looks like: `source.type.name`",
Subject: block.DefRange.Ptr(),
2019-12-17 11:25:56 +01:00
})
continue
}
build.Sources = append(build.Sources, ref)
2019-12-17 11:25:56 +01:00
}
content, moreDiags := b.Config.Content(buildSchema)
diags = append(diags, moreDiags...)
2020-02-17 17:15:52 +01:00
if diags.HasErrors() {
return nil, diags
}
2019-10-14 17:02:53 +02:00
for _, block := range content.Blocks {
switch block.Type {
case sourceLabel:
ref, moreDiags := p.decodeBuildSource(block)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
continue
}
build.Sources = append(build.Sources, ref)
2019-12-17 11:25:56 +01:00
case buildProvisionerLabel:
p, moreDiags := p.decodeProvisioner(block)
2019-10-14 17:02:53 +02:00
diags = append(diags, moreDiags...)
2019-12-17 11:25:56 +01:00
if moreDiags.HasErrors() {
continue
}
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
case buildPostProcessorLabel:
pp, moreDiags := p.decodePostProcessor(block)
2019-10-14 17:02:53 +02:00
diags = append(diags, moreDiags...)
2019-12-17 11:25:56 +01:00
if moreDiags.HasErrors() {
continue
}
build.PostProcessors = append(build.PostProcessors, pp)
2019-10-14 17:02:53 +02:00
}
}
return build, diags
}