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

136 lines
3.6 KiB
Go
Raw Normal View History

2019-10-14 17:02:53 +02:00
package hcl2template
import (
"fmt"
"strconv"
2019-10-14 17:02:53 +02:00
"github.com/hashicorp/hcl/v2"
2019-12-17 11:25:56 +01:00
"github.com/hashicorp/packer/packer"
2019-10-14 17:02:53 +02:00
)
// SourceBlock references an HCL 'source' block.
type SourceBlock struct {
2019-10-14 17:02:53 +02:00
// Type of source; ex: virtualbox-iso
Type string
// Given name; if any
Name string
2019-12-17 11:25:56 +01:00
block *hcl.Block
2020-06-02 11:52:11 +02:00
// addition will be merged into block to allow user to override builder settings
// per build.source block.
addition hcl.Body
2019-10-14 17:02:53 +02:00
}
// decodeBuildSource reads a used source block from a build:
// build {
// source "type.example" {}
// }
func (p *Parser) decodeBuildSource(block *hcl.Block) (SourceRef, hcl.Diagnostics) {
ref := sourceRefFromString(block.Labels[0])
ref.addition = block.Body
return ref, nil
}
func (p *Parser) decodeSource(block *hcl.Block) (SourceBlock, hcl.Diagnostics) {
source := SourceBlock{
2019-12-17 11:25:56 +01:00
Type: block.Labels[0],
Name: block.Labels[1],
block: block,
2019-10-14 17:02:53 +02:00
}
var diags hcl.Diagnostics
2019-12-17 11:25:56 +01:00
if !p.BuilderSchemas.Has(source.Type) {
2019-10-14 17:02:53 +02:00
diags = append(diags, &hcl.Diagnostic{
2019-12-17 11:25:56 +01:00
Summary: "Unknown " + buildSourceLabel + " type " + source.Type,
Subject: block.LabelRanges[0].Ptr(),
Detail: fmt.Sprintf("known builders: %v", p.BuilderSchemas.List()),
Severity: hcl.DiagError,
2019-10-14 17:02:53 +02:00
})
return source, diags
2019-10-14 17:02:53 +02:00
}
return source, diags
}
func (cfg *PackerConfig) startBuilder(source SourceBlock, ectx *hcl.EvalContext, opts packer.GetBuildsOptions) (packer.Builder, hcl.Diagnostics, []string) {
2019-12-17 11:25:56 +01:00
var diags hcl.Diagnostics
builder, err := cfg.builderSchemas.Start(source.Type)
2019-12-17 11:25:56 +01:00
if err != nil {
diags = append(diags, &hcl.Diagnostic{
Summary: "Failed to load " + sourceLabel + " type",
Detail: err.Error(),
Subject: &source.block.LabelRanges[0],
})
return builder, diags, nil
2019-12-17 11:25:56 +01:00
}
body := source.block.Body
if source.addition != nil {
body = hcl.MergeBodies([]hcl.Body{source.block.Body, source.addition})
}
decoded, moreDiags := decodeHCL2Spec(body, ectx, builder)
2019-12-17 11:25:56 +01:00
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
return nil, diags, nil
2019-12-17 11:25:56 +01:00
}
2019-12-17 16:31:22 +01:00
// Note: HCL prepares inside of the Start func, but Json does not. Json
// builds are instead prepared only in command/build.go
// TODO: either make json prepare when plugins are loaded, or make HCL
// prepare at a later step, to make builds from different template types
// easier to reason about.
builderVars := source.builderVariables()
builderVars["packer_debug"] = strconv.FormatBool(opts.Debug)
builderVars["packer_force"] = strconv.FormatBool(opts.Force)
builderVars["packer_on_error"] = opts.OnError
generatedVars, warning, err := builder.Prepare(builderVars, decoded)
2019-12-17 11:25:56 +01:00
moreDiags = warningErrorsToDiags(source.block, warning, err)
diags = append(diags, moreDiags...)
return builder, diags, generatedVars
2019-12-17 11:25:56 +01:00
}
// These variables will populate the PackerConfig inside of the builders.
2020-04-09 11:14:37 +02:00
func (source *SourceBlock) builderVariables() map[string]string {
return map[string]string{
"packer_build_name": source.Name,
"packer_builder_type": source.Type,
}
}
func (source *SourceBlock) Ref() SourceRef {
2019-10-14 17:02:53 +02:00
return SourceRef{
Type: source.Type,
Name: source.Name,
}
}
type SourceRef struct {
Type string
Name string
// The content of this body will be merged into a new block to allow to
// override builder settings per build section.
addition hcl.Body
}
2020-06-02 11:51:48 +02:00
// the 'addition' field makes of ref a different entry in the sources map, so
// Ref is here to make sure only one is returned.
func (r *SourceRef) Ref() SourceRef {
return SourceRef{
Type: r.Type,
Name: r.Name,
}
2019-10-14 17:02:53 +02:00
}
// NoSource is the zero value of sourceRef, representing the absense of an
// source.
var NoSource SourceRef
func (r SourceRef) String() string {
return fmt.Sprintf("%s.%s", r.Type, r.Name)
}