Fix force flag for hcl2 provisioners and post-processors (#10571)
This commit is contained in:
parent
f588c46fb6
commit
ef4afafde9
|
@ -12,6 +12,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer/builder/file"
|
||||
"github.com/hashicorp/packer/builder/null"
|
||||
|
@ -695,6 +696,79 @@ func testHCLOnlyExceptFlags(t *testing.T, args, present, notPresent []string) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHCL2PostProcessorForceFlag(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
UUID, _ := uuid.GenerateUUID()
|
||||
// Manifest will only clean with force if the build's PACKER_RUN_UUID are different
|
||||
os.Setenv("PACKER_RUN_UUID", UUID)
|
||||
defer os.Unsetenv("PACKER_RUN_UUID")
|
||||
|
||||
args := []string{
|
||||
filepath.Join(testFixture("hcl"), "force.pkr.hcl"),
|
||||
}
|
||||
fCheck := fileCheck{
|
||||
expectedContent: map[string]string{
|
||||
"manifest.json": fmt.Sprintf(`{
|
||||
"builds": [
|
||||
{
|
||||
"name": "potato",
|
||||
"builder_type": "null",
|
||||
"files": null,
|
||||
"artifact_id": "Null",
|
||||
"packer_run_uuid": %q,
|
||||
"custom_data": null
|
||||
}
|
||||
],
|
||||
"last_run_uuid": %q
|
||||
}`, UUID, UUID),
|
||||
},
|
||||
}
|
||||
defer fCheck.cleanup(t)
|
||||
|
||||
c := &BuildCommand{
|
||||
Meta: testMetaFile(t),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
fatalCommand(t, c.Meta)
|
||||
}
|
||||
fCheck.verify(t)
|
||||
|
||||
// Second build should override previous manifest
|
||||
UUID, _ = uuid.GenerateUUID()
|
||||
os.Setenv("PACKER_RUN_UUID", UUID)
|
||||
|
||||
args = []string{
|
||||
"-force",
|
||||
filepath.Join(testFixture("hcl"), "force.pkr.hcl"),
|
||||
}
|
||||
fCheck = fileCheck{
|
||||
expectedContent: map[string]string{
|
||||
"manifest.json": fmt.Sprintf(`{
|
||||
"builds": [
|
||||
{
|
||||
"name": "potato",
|
||||
"builder_type": "null",
|
||||
"files": null,
|
||||
"artifact_id": "Null",
|
||||
"packer_run_uuid": %q,
|
||||
"custom_data": null
|
||||
}
|
||||
],
|
||||
"last_run_uuid": %q
|
||||
}`, UUID, UUID),
|
||||
},
|
||||
}
|
||||
|
||||
c = &BuildCommand{
|
||||
Meta: testMetaFile(t),
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
fatalCommand(t, c.Meta)
|
||||
}
|
||||
fCheck.verify(t)
|
||||
}
|
||||
|
||||
func TestBuildCommand_HCLOnlyExceptOptions(t *testing.T) {
|
||||
tests := []struct {
|
||||
args []string
|
||||
|
|
|
@ -42,13 +42,13 @@ build {
|
|||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
only = ["sources.file.vanilla"]
|
||||
only = ["file.vanilla"]
|
||||
name = "tomato"
|
||||
inline = [ "echo apple > tomato.txt" ]
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
only = ["sources.file.chocolate"]
|
||||
only = ["file.chocolate"]
|
||||
inline = [ "echo apple > unnamed.txt" ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
source "null" "potato" {
|
||||
communicator = "none"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["sources.null.potato"]
|
||||
|
||||
post-processor "manifest" {
|
||||
output = "manifest.json"
|
||||
strip_time = true
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package hcl2template
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/gohcl"
|
||||
|
@ -64,11 +65,17 @@ func (cfg *PackerConfig) startPostProcessor(source SourceUseBlock, pp *PostProce
|
|||
})
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
builderVars := source.builderVariables()
|
||||
builderVars["packer_debug"] = strconv.FormatBool(cfg.debug)
|
||||
builderVars["packer_force"] = strconv.FormatBool(cfg.force)
|
||||
builderVars["packer_on_error"] = cfg.onError
|
||||
|
||||
hclPostProcessor := &HCL2PostProcessor{
|
||||
PostProcessor: postProcessor,
|
||||
postProcessorBlock: pp,
|
||||
evalContext: ectx,
|
||||
builderVariables: source.builderVariables(),
|
||||
builderVariables: builderVars,
|
||||
}
|
||||
err = hclPostProcessor.HCL2Prepare(nil)
|
||||
if err != nil {
|
||||
|
|
|
@ -2,6 +2,7 @@ package hcl2template
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
|
@ -152,11 +153,16 @@ func (cfg *PackerConfig) startProvisioner(source SourceUseBlock, pb *Provisioner
|
|||
return nil, diags
|
||||
}
|
||||
|
||||
builderVars := source.builderVariables()
|
||||
builderVars["packer_debug"] = strconv.FormatBool(cfg.debug)
|
||||
builderVars["packer_force"] = strconv.FormatBool(cfg.force)
|
||||
builderVars["packer_on_error"] = cfg.onError
|
||||
|
||||
hclProvisioner := &HCL2Provisioner{
|
||||
Provisioner: provisioner,
|
||||
provisionerBlock: pb,
|
||||
evalContext: ectx,
|
||||
builderVariables: source.builderVariables(),
|
||||
builderVariables: builderVars,
|
||||
}
|
||||
|
||||
if pb.Override != nil {
|
||||
|
|
|
@ -52,11 +52,15 @@ type PackerConfig struct {
|
|||
// Builds is the list of Build blocks defined in the config files.
|
||||
Builds Builds
|
||||
|
||||
except []glob.Glob
|
||||
only []glob.Glob
|
||||
|
||||
parser *Parser
|
||||
files []*hcl.File
|
||||
|
||||
// Fields passed as command line flags
|
||||
except []glob.Glob
|
||||
only []glob.Glob
|
||||
force bool
|
||||
debug bool
|
||||
onError string
|
||||
}
|
||||
|
||||
type ValidationOptions struct {
|
||||
|
@ -408,6 +412,10 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu
|
|||
res := []packersdk.Build{}
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
cfg.debug = opts.Debug
|
||||
cfg.force = opts.Force
|
||||
cfg.onError = opts.OnError
|
||||
|
||||
for _, build := range cfg.Builds {
|
||||
for _, srcUsage := range build.Sources {
|
||||
src, found := cfg.Sources[srcUsage.SourceRef]
|
||||
|
@ -466,7 +474,7 @@ func (cfg *PackerConfig) GetBuilds(opts packer.GetBuildsOptions) ([]packersdk.Bu
|
|||
}
|
||||
}
|
||||
|
||||
builder, moreDiags, generatedVars := cfg.startBuilder(srcUsage, cfg.EvalContext(BuildContext, nil), opts)
|
||||
builder, moreDiags, generatedVars := cfg.startBuilder(srcUsage, cfg.EvalContext(BuildContext, nil))
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
continue
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/hashicorp/hcl/v2/gohcl"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
hcl2shim "github.com/hashicorp/packer/hcl2template/shim"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
|
@ -96,7 +95,7 @@ func (p *Parser) decodeSource(block *hcl.Block) (SourceBlock, hcl.Diagnostics) {
|
|||
return source, diags
|
||||
}
|
||||
|
||||
func (cfg *PackerConfig) startBuilder(source SourceUseBlock, ectx *hcl.EvalContext, opts packer.GetBuildsOptions) (packersdk.Builder, hcl.Diagnostics, []string) {
|
||||
func (cfg *PackerConfig) startBuilder(source SourceUseBlock, ectx *hcl.EvalContext) (packersdk.Builder, hcl.Diagnostics, []string) {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
builder, err := cfg.parser.PluginConfig.Builders.Start(source.Type)
|
||||
|
@ -127,9 +126,9 @@ func (cfg *PackerConfig) startBuilder(source SourceUseBlock, ectx *hcl.EvalConte
|
|||
// 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
|
||||
builderVars["packer_debug"] = strconv.FormatBool(cfg.debug)
|
||||
builderVars["packer_force"] = strconv.FormatBool(cfg.force)
|
||||
builderVars["packer_on_error"] = cfg.onError
|
||||
|
||||
generatedVars, warning, err := builder.Prepare(builderVars, decoded)
|
||||
moreDiags = warningErrorsToDiags(cfg.Sources[source.SourceRef].block, warning, err)
|
||||
|
|
|
@ -72,7 +72,7 @@ build {
|
|||
post-processor "checksum" {
|
||||
checksum_types = [ "md5", "sha512" ]
|
||||
keep_input_artifact = true
|
||||
only = ["source.amazon-ebs.example"]
|
||||
only = ["amazon-ebs.example"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -58,7 +58,7 @@ build {
|
|||
]
|
||||
provisioner "shell" {
|
||||
# This provisioner only runs for the 'first-example' source.
|
||||
only = ["source.amazon-ebs.first-example"]
|
||||
only = ["amazon-ebs.first-example"]
|
||||
|
||||
inline = [
|
||||
"echo provisioning all the things",
|
||||
|
|
|
@ -32,12 +32,12 @@ build {
|
|||
}
|
||||
|
||||
provisioner "shell-local" {
|
||||
only = ["source.amazon-ebs.first-example"]
|
||||
only = ["amazon-ebs.first-example"]
|
||||
inline = ["echo I will only run for the second example source"]
|
||||
}
|
||||
|
||||
provisioner "shell-local" {
|
||||
except = ["source.amazon-ebs.second-example-local-name"]
|
||||
except = ["amazon-ebs.second-example-local-name"]
|
||||
inline = ["echo I will never run for the second example source"]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue