2019-10-14 11:02:53 -04:00
|
|
|
package hcl2template
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
2019-12-17 05:25:56 -05:00
|
|
|
"github.com/hashicorp/hcl/v2/gohcl"
|
|
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
2019-10-14 11:02:53 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
buildFromLabel = "from"
|
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
buildSourceLabel = "source"
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
buildProvisionerLabel = "provisioner"
|
|
|
|
|
|
|
|
buildPostProcessorLabel = "post-processor"
|
2020-07-28 04:02:37 -04:00
|
|
|
|
|
|
|
buildPostProcessorsLabel = "post-processors"
|
2019-10-14 11:02:53 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
var buildSchema = &hcl.BodySchema{
|
|
|
|
Blocks: []hcl.BlockHeaderSchema{
|
2019-12-17 05:25:56 -05:00
|
|
|
{Type: buildFromLabel, LabelNames: []string{"type"}},
|
2020-05-25 11:09:37 -04:00
|
|
|
{Type: sourceLabel, LabelNames: []string{"reference"}},
|
2019-12-17 05:25:56 -05:00
|
|
|
{Type: buildProvisionerLabel, LabelNames: []string{"type"}},
|
|
|
|
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
|
2020-07-28 04:02:37 -04:00
|
|
|
{Type: buildPostProcessorsLabel, LabelNames: []string{}},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var postProcessorsSchema = &hcl.BodySchema{
|
|
|
|
Blocks: []hcl.BlockHeaderSchema{
|
|
|
|
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
|
2019-10-14 11:02:53 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
|
|
|
// BuildBlock references an HCL 'build' block and it content, for example :
|
|
|
|
//
|
|
|
|
// build {
|
|
|
|
// sources = [
|
|
|
|
// ...
|
|
|
|
// ]
|
|
|
|
// provisioner "" { ... }
|
|
|
|
// post-processor "" { ... }
|
|
|
|
// }
|
2019-12-17 05:25:56 -05:00
|
|
|
type BuildBlock struct {
|
2020-05-18 01:13:35 -04:00
|
|
|
// Name is a string representing the named build to show in the logs
|
|
|
|
Name string
|
|
|
|
|
2020-06-23 05:58:34 -04:00
|
|
|
// A description of what this build does, it could be used in a inspect
|
|
|
|
// call for example.
|
|
|
|
Description string
|
|
|
|
|
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
|
|
|
// 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 05:25:56 -05:00
|
|
|
ProvisionerBlocks []*ProvisionerBlock
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2020-07-28 04:02:37 -04:00
|
|
|
// PostProcessorLists references the lists of lists of HCL post-processors
|
|
|
|
// block that will be run against the artifacts from the provisioning
|
|
|
|
// steps.
|
|
|
|
PostProcessorsLists [][]*PostProcessorBlock
|
2019-10-14 11:02:53 -04:00
|
|
|
|
|
|
|
HCL2Ref HCL2Ref
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
type Builds []*BuildBlock
|
|
|
|
|
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
|
|
|
// decodeBuildConfig is called when a 'build' block has been detected. It will
|
|
|
|
// load the references to the contents of the build block.
|
2020-08-05 11:41:20 -04:00
|
|
|
func (p *Parser) decodeBuildConfig(block *hcl.Block, cfg *PackerConfig) (*BuildBlock, hcl.Diagnostics) {
|
2019-12-17 05:25:56 -05:00
|
|
|
build := &BuildBlock{}
|
|
|
|
|
|
|
|
var b struct {
|
2020-05-18 01:13:35 -04:00
|
|
|
Name string `hcl:"name,optional"`
|
2020-06-23 05:58:34 -04:00
|
|
|
Description string `hcl:"description,optional"`
|
2020-05-28 10:35:53 -04:00
|
|
|
FromSources []string `hcl:"sources,optional"`
|
2019-12-17 05:25:56 -05:00
|
|
|
Config hcl.Body `hcl:",remain"`
|
|
|
|
}
|
|
|
|
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
2020-02-17 11:15:52 -05:00
|
|
|
if diags.HasErrors() {
|
|
|
|
return nil, diags
|
|
|
|
}
|
2019-12-17 05:25:56 -05:00
|
|
|
|
2020-05-18 01:13:35 -04:00
|
|
|
build.Name = b.Name
|
2020-06-23 05:58:34 -04:00
|
|
|
build.Description = b.Description
|
2020-05-18 01:13:35 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
for _, buildFrom := range b.FromSources {
|
|
|
|
ref := sourceRefFromString(buildFrom)
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2020-01-06 11:10:12 -05:00
|
|
|
if ref == NoSource ||
|
|
|
|
!hclsyntax.ValidIdentifier(ref.Type) ||
|
2019-12-17 05:25:56 -05:00
|
|
|
!hclsyntax.ValidIdentifier(ref.Name) {
|
|
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
|
|
Severity: hcl.DiagError,
|
|
|
|
Summary: "Invalid " + sourceLabel + " reference",
|
2020-01-06 11:10:12 -05: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 05:25:56 -05:00
|
|
|
"may contain only letters, digits, underscores, and dashes." +
|
|
|
|
"A valid source reference looks like: `source.type.name`",
|
2020-01-06 08:29:43 -05:00
|
|
|
Subject: block.DefRange.Ptr(),
|
2019-12-17 05:25:56 -05:00
|
|
|
})
|
|
|
|
continue
|
|
|
|
}
|
2019-10-14 11:02:53 -04:00
|
|
|
|
Hcl2 input variables, local variables and functions (#8588)
Mainly redefine or reused what Terraform did.
* allow to used `variables`, `variable` and `local` blocks
* import the following functions and their docs from Terraform: abs, abspath, basename, base64decode, base64encode, bcrypt, can, ceil, chomp, chunklist, cidrhost, cidrnetmask, cidrsubnet, cidrsubnets, coalesce, coalescelist, compact, concat, contains, convert, csvdecode, dirname, distinct, element, file, fileexists, fileset, flatten, floor, format, formatdate, formatlist, indent, index, join, jsondecode, jsonencode, keys, length, log, lookup, lower, max, md5, merge, min, parseint, pathexpand, pow, range, reverse, rsadecrypt, setintersection, setproduct, setunion, sha1, sha256, sha512, signum, slice, sort, split, strrev, substr, timestamp, timeadd, title, trim, trimprefix, trimspace, trimsuffix, try, upper, urlencode, uuidv4, uuidv5, values, yamldecode, yamlencode, zipmap.
2020-02-06 05:49:21 -05:00
|
|
|
build.Sources = append(build.Sources, ref)
|
2019-12-17 05:25:56 -05:00
|
|
|
}
|
|
|
|
|
2020-01-06 08:29:43 -05:00
|
|
|
content, moreDiags := b.Config.Content(buildSchema)
|
|
|
|
diags = append(diags, moreDiags...)
|
2020-02-17 11:15:52 -05:00
|
|
|
if diags.HasErrors() {
|
|
|
|
return nil, diags
|
|
|
|
}
|
2019-10-14 11:02:53 -04:00
|
|
|
for _, block := range content.Blocks {
|
|
|
|
switch block.Type {
|
2020-05-25 11:09:37 -04:00
|
|
|
case sourceLabel:
|
|
|
|
ref, moreDiags := p.decodeBuildSource(block)
|
|
|
|
diags = append(diags, moreDiags...)
|
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
build.Sources = append(build.Sources, ref)
|
2019-12-17 05:25:56 -05:00
|
|
|
case buildProvisionerLabel:
|
2020-08-05 11:41:20 -04:00
|
|
|
p, moreDiags := p.decodeProvisioner(block, cfg)
|
2019-10-14 11:02:53 -04:00
|
|
|
diags = append(diags, moreDiags...)
|
2019-12-17 05:25:56 -05:00
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
|
|
|
|
case buildPostProcessorLabel:
|
2020-01-16 06:08:39 -05:00
|
|
|
pp, moreDiags := p.decodePostProcessor(block)
|
2019-10-14 11:02:53 -04:00
|
|
|
diags = append(diags, moreDiags...)
|
2019-12-17 05:25:56 -05:00
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
2020-07-28 04:02:37 -04:00
|
|
|
build.PostProcessorsLists = append(build.PostProcessorsLists, []*PostProcessorBlock{pp})
|
|
|
|
case buildPostProcessorsLabel:
|
|
|
|
|
|
|
|
content, moreDiags := block.Body.Content(postProcessorsSchema)
|
|
|
|
diags = append(diags, moreDiags...)
|
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
errored := false
|
|
|
|
postProcessors := []*PostProcessorBlock{}
|
|
|
|
for _, block := range content.Blocks {
|
|
|
|
pp, moreDiags := p.decodePostProcessor(block)
|
|
|
|
diags = append(diags, moreDiags...)
|
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
errored = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
postProcessors = append(postProcessors, pp)
|
|
|
|
}
|
|
|
|
if errored == false {
|
|
|
|
build.PostProcessorsLists = append(build.PostProcessorsLists, postProcessors)
|
|
|
|
}
|
2019-10-14 11:02:53 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return build, diags
|
|
|
|
}
|