HCL2: allow to use keep_input_artifact in post processors (#9477)

* HCL2: allow to use keep_input_artifact in post processors
* add basic test
* add docs
This commit is contained in:
Adrien Delorme 2020-06-25 09:36:48 +02:00 committed by GitHub
parent 82dc1bf7a7
commit c2975140cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 35 deletions

View File

@ -116,7 +116,7 @@ build {
} }
} }
post-processor "amazon-import" { post-processor "amazon-import" {
name = "something" name = "something"
string = "string" string = "string"
int = 42 int = 42
@ -124,6 +124,7 @@ build {
bool = true bool = true
trilean = true trilean = true
duration = "10s" duration = "10s"
keep_input_artifact = true
map_string_string = { map_string_string = {
a = "b" a = "b"
c = "d" c = "d"
@ -164,7 +165,7 @@ build {
} }
} }
post-processor "amazon-import" { post-processor "amazon-import" {
string = "string" string = "string"
int = 42 int = 42
int64 = 43 int64 = 43

View File

@ -10,9 +10,10 @@ import (
// ProvisionerBlock references a detected but unparsed post processor // ProvisionerBlock references a detected but unparsed post processor
type PostProcessorBlock struct { type PostProcessorBlock struct {
PType string PType string
PName string PName string
OnlyExcept OnlyExcept OnlyExcept OnlyExcept
KeepInputArtifact *bool
HCL2Ref HCL2Ref
} }
@ -23,10 +24,11 @@ func (p *PostProcessorBlock) String() string {
func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) { func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) {
var b struct { var b struct {
Name string `hcl:"name,optional"` Name string `hcl:"name,optional"`
Only []string `hcl:"only,optional"` Only []string `hcl:"only,optional"`
Except []string `hcl:"except,optional"` Except []string `hcl:"except,optional"`
Rest hcl.Body `hcl:",remain"` KeepInputArtifact *bool `hcl:"keep_input_artifact,optional"`
Rest hcl.Body `hcl:",remain"`
} }
diags := gohcl.DecodeBody(block.Body, nil, &b) diags := gohcl.DecodeBody(block.Body, nil, &b)
if diags.HasErrors() { if diags.HasErrors() {
@ -34,10 +36,11 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl
} }
postProcessor := &PostProcessorBlock{ postProcessor := &PostProcessorBlock{
PType: block.Labels[0], PType: block.Labels[0],
PName: b.Name, PName: b.Name,
OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except}, OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except},
HCL2Ref: newHCL2Ref(block, b.Rest), HCL2Ref: newHCL2Ref(block, b.Rest),
KeepInputArtifact: b.KeepInputArtifact,
} }
diags = diags.Extend(postProcessor.OnlyExcept.Validate()) diags = diags.Extend(postProcessor.OnlyExcept.Validate())

View File

@ -271,9 +271,10 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceBlock, blocks [
continue continue
} }
res = append(res, packer.CoreBuildPostProcessor{ res = append(res, packer.CoreBuildPostProcessor{
PostProcessor: postProcessor, PostProcessor: postProcessor,
PName: ppb.PName, PName: ppb.PName,
PType: ppb.PType, PType: ppb.PType,
KeepInputArtifact: ppb.KeepInputArtifact,
}) })
} }

View File

@ -11,6 +11,7 @@ import (
var ( var (
refVBIsoUbuntu1204 = SourceRef{Type: "virtualbox-iso", Name: "ubuntu-1204"} refVBIsoUbuntu1204 = SourceRef{Type: "virtualbox-iso", Name: "ubuntu-1204"}
refAWSEBSUbuntu1604 = SourceRef{Type: "amazon-ebs", Name: "ubuntu-1604"} refAWSEBSUbuntu1604 = SourceRef{Type: "amazon-ebs", Name: "ubuntu-1604"}
pTrue = pointerToBool(true)
) )
func TestParser_complete(t *testing.T) { func TestParser_complete(t *testing.T) {
@ -90,8 +91,9 @@ func TestParser_complete(t *testing.T) {
}, },
PostProcessors: []*PostProcessorBlock{ PostProcessors: []*PostProcessorBlock{
{ {
PType: "amazon-import", PType: "amazon-import",
PName: "something", PName: "something",
KeepInputArtifact: pTrue,
}, },
{ {
PType: "amazon-import", PType: "amazon-import",
@ -117,9 +119,10 @@ func TestParser_complete(t *testing.T) {
PostProcessors: [][]packer.CoreBuildPostProcessor{ PostProcessors: [][]packer.CoreBuildPostProcessor{
{ {
{ {
PType: "amazon-import", PType: "amazon-import",
PName: "something", PName: "something",
PostProcessor: basicMockPostProcessor, PostProcessor: basicMockPostProcessor,
KeepInputArtifact: pTrue,
}, },
{ {
PType: "amazon-import", PType: "amazon-import",
@ -152,9 +155,10 @@ func TestParser_complete(t *testing.T) {
PostProcessors: [][]packer.CoreBuildPostProcessor{ PostProcessors: [][]packer.CoreBuildPostProcessor{
{ {
{ {
PType: "amazon-import", PType: "amazon-import",
PName: "something", PName: "something",
PostProcessor: basicMockPostProcessor, PostProcessor: basicMockPostProcessor,
KeepInputArtifact: pTrue,
}, },
{ {
PType: "amazon-import", PType: "amazon-import",
@ -191,3 +195,7 @@ func TestParser_ValidateFilterOption(t *testing.T) {
}) })
} }
} }
func pointerToBool(b bool) *bool {
return &b
}

View File

@ -115,7 +115,7 @@ type CoreBuildPostProcessor struct {
PType string PType string
PName string PName string
config map[string]interface{} config map[string]interface{}
keepInputArtifact *bool KeepInputArtifact *bool
} }
// CoreBuildProvisioner keeps track of the provisioner and the configuration of // CoreBuildProvisioner keeps track of the provisioner and the configuration of
@ -341,15 +341,15 @@ PostProcessorRunSeqLoop:
// Exception: for postprocessors that will fail/become // Exception: for postprocessors that will fail/become
// useless if keep isn't true, heed forceOverride and keep the // useless if keep isn't true, heed forceOverride and keep the
// input artifact regardless of user preference. // input artifact regardless of user preference.
if corePP.keepInputArtifact != nil { if corePP.KeepInputArtifact != nil {
if defaultKeep && *corePP.keepInputArtifact == false && forceOverride { if defaultKeep && *corePP.KeepInputArtifact == false && forceOverride {
log.Printf("The %s post-processor forces "+ log.Printf("The %s post-processor forces "+
"keep_input_artifact=true to preserve integrity of the"+ "keep_input_artifact=true to preserve integrity of the"+
"build chain. User-set keep_input_artifact=false will be"+ "build chain. User-set keep_input_artifact=false will be"+
"ignored.", corePP.PType) "ignored.", corePP.PType)
} else { } else {
// User overrides default. // User overrides default.
keep = *corePP.keepInputArtifact keep = *corePP.KeepInputArtifact
} }
} }
if i == 0 { if i == 0 {

View File

@ -341,7 +341,7 @@ func (c *Core) Build(n string) (Build, error) {
PType: rawP.Type, PType: rawP.Type,
PName: rawP.Name, PName: rawP.Name,
config: rawP.Config, config: rawP.Config,
keepInputArtifact: rawP.KeepInputArtifact, KeepInputArtifact: rawP.KeepInputArtifact,
}) })
} }

View File

@ -17,8 +17,8 @@ The `post-processor` block defines how a post-processor is configured.
build { build {
# ... # ...
post-processor "checksum" { post-processor "checksum" {
checksum_types = [ "md5", "sha512" ] checksum_types = [ "md5", "sha512" ] # checksum the artifact
keep_input_artifact = true keep_input_artifact = true # keep the artifact
} }
} }
``` ```
@ -28,12 +28,32 @@ the provisioner(s). Post-processors are optional, and they can be used to
upload artifacts, re-package, or more. The list of available post-processors upload artifacts, re-package, or more. The list of available post-processors
can be found in the [post-processors](/docs/post-processors) section. can be found in the [post-processors](/docs/post-processors) section.
-> Note: The input 'artifact' received by a post-processor will be automatically
deleted.
# Keep an input artifact
To prevent an input artifact from being deleted, you can set the
`keep_input_artifact` field to true to make Packer keep both artifacts. For
example if we want to checksum an artifact and keep the artifact:
```hcl
# builds.pkr.hcl
build {
# ...
post-processor "checksum" {
checksum_types = [ "md5", "sha512" ]
keep_input_artifact = true
}
}
```
# Run on Specific Builds # Run on Specific Builds
You can use the `only` or `except` configurations to run a post-processor only You can use the `only` or `except` configurations to run a post-processor only
with specific builds. These two configurations do what you expect: `only` will with specific sources. These two configurations do what you expect: `only` will
only run the post-processor on the specified builds and `except` will run the only run the post-processor on the specified sources and `except` will run the
post-processor on anything other than the specified builds. post-processor on anything other than the specified sources.
An example of `only` being used is shown below, but the usage of `except` is An example of `only` being used is shown below, but the usage of `except` is
effectively the same: effectively the same:
@ -50,4 +70,4 @@ build {
} }
``` ```
The values within `only` or `except` are _build names_, not builder types. The values within `only` or `except` are _source names_, not builder types.