Enable only/except for provisioners and post-processors (#9357)
This commit is contained in:
parent
fd0764d668
commit
0d7c5dc670
|
@ -30,6 +30,7 @@ func getBasicParser() *Parser {
|
|||
},
|
||||
PostProcessorsSchemas: packer.MapOfPostProcessor{
|
||||
"amazon-import": func() (packer.PostProcessor, error) { return &MockPostProcessor{}, nil },
|
||||
"manifest": func() (packer.PostProcessor, error) { return &MockPostProcessor{}, nil },
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
// starts resources to provision them.
|
||||
build {
|
||||
sources = [
|
||||
"source.virtualbox-iso.ubuntu-1204",
|
||||
"source.amazon-ebs.ubuntu-1604",
|
||||
]
|
||||
|
||||
post-processor "amazon-import" {
|
||||
only = ["virtualbox-iso.ubuntu-1204"]
|
||||
}
|
||||
post-processor "manifest" {
|
||||
except = ["virtualbox-iso.ubuntu-1204"]
|
||||
}
|
||||
}
|
||||
|
||||
source "virtualbox-iso" "ubuntu-1204" {
|
||||
}
|
||||
|
||||
source "amazon-ebs" "ubuntu-1604" {
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
// starts resources to provision them.
|
||||
build {
|
||||
sources = [
|
||||
"source.virtualbox-iso.ubuntu-1204",
|
||||
"source.amazon-ebs.ubuntu-1604",
|
||||
]
|
||||
|
||||
provisioner "shell" {
|
||||
only = ["virtualbox-iso.ubuntu-1204"]
|
||||
}
|
||||
provisioner "file" {
|
||||
except = ["virtualbox-iso.ubuntu-1204"]
|
||||
}
|
||||
}
|
||||
|
||||
source "virtualbox-iso" "ubuntu-1204" {
|
||||
}
|
||||
|
||||
source "amazon-ebs" "ubuntu-1604" {
|
||||
}
|
|
@ -10,8 +10,9 @@ import (
|
|||
|
||||
// ProvisionerBlock references a detected but unparsed post processor
|
||||
type PostProcessorBlock struct {
|
||||
PType string
|
||||
PName string
|
||||
PType string
|
||||
PName string
|
||||
OnlyExcept OnlyExcept
|
||||
|
||||
HCL2Ref
|
||||
}
|
||||
|
@ -22,8 +23,10 @@ func (p *PostProcessorBlock) String() string {
|
|||
|
||||
func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl.Diagnostics) {
|
||||
var b struct {
|
||||
Name string `hcl:"name,optional"`
|
||||
Rest hcl.Body `hcl:",remain"`
|
||||
Name string `hcl:"name,optional"`
|
||||
Only []string `hcl:"only,optional"`
|
||||
Except []string `hcl:"except,optional"`
|
||||
Rest hcl.Body `hcl:",remain"`
|
||||
}
|
||||
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
||||
if diags.HasErrors() {
|
||||
|
@ -31,9 +34,15 @@ func (p *Parser) decodePostProcessor(block *hcl.Block) (*PostProcessorBlock, hcl
|
|||
}
|
||||
|
||||
postProcessor := &PostProcessorBlock{
|
||||
PType: block.Labels[0],
|
||||
PName: b.Name,
|
||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||
PType: block.Labels[0],
|
||||
PName: b.Name,
|
||||
OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except},
|
||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||
}
|
||||
|
||||
diags = diags.Extend(postProcessor.OnlyExcept.Validate())
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
if !p.PostProcessorsSchemas.Has(postProcessor.PType) {
|
||||
|
|
|
@ -9,6 +9,52 @@ import (
|
|||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
// OnlyExcept is a struct that is meant to be embedded that contains the
|
||||
// logic required for "only" and "except" meta-parameters.
|
||||
type OnlyExcept struct {
|
||||
Only []string `json:"only,omitempty"`
|
||||
Except []string `json:"except,omitempty"`
|
||||
}
|
||||
|
||||
// Skip says whether or not to skip the build with the given name.
|
||||
func (o *OnlyExcept) Skip(n string) bool {
|
||||
if len(o.Only) > 0 {
|
||||
for _, v := range o.Only {
|
||||
if v == n {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
if len(o.Except) > 0 {
|
||||
for _, v := range o.Except {
|
||||
if v == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate validates that the OnlyExcept settings are correct for a thing.
|
||||
func (o *OnlyExcept) Validate() hcl.Diagnostics {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
if len(o.Only) > 0 && len(o.Except) > 0 {
|
||||
diags = diags.Append(&hcl.Diagnostic{
|
||||
Summary: "only one of 'only' or 'except' may be specified",
|
||||
Severity: hcl.DiagError,
|
||||
})
|
||||
}
|
||||
|
||||
return diags
|
||||
}
|
||||
|
||||
// ProvisionerBlock references a detected but unparsed provisioner
|
||||
type ProvisionerBlock struct {
|
||||
PType string
|
||||
|
@ -16,6 +62,7 @@ type ProvisionerBlock struct {
|
|||
PauseBefore time.Duration
|
||||
MaxRetries int
|
||||
Timeout time.Duration
|
||||
OnlyExcept OnlyExcept
|
||||
HCL2Ref
|
||||
}
|
||||
|
||||
|
@ -29,6 +76,8 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
|
|||
PauseBefore string `hcl:"pause_before,optional"`
|
||||
MaxRetries int `hcl:"max_retries,optional"`
|
||||
Timeout string `hcl:"timeout,optional"`
|
||||
Only []string `hcl:"only,optional"`
|
||||
Except []string `hcl:"except,optional"`
|
||||
Rest hcl.Body `hcl:",remain"`
|
||||
}
|
||||
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
||||
|
@ -40,9 +89,15 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
|
|||
PType: block.Labels[0],
|
||||
PName: b.Name,
|
||||
MaxRetries: b.MaxRetries,
|
||||
OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except},
|
||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||
}
|
||||
|
||||
diags = diags.Extend(provisioner.OnlyExcept.Validate())
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
if b.PauseBefore != "" {
|
||||
pauseBefore, err := time.ParseDuration(b.PauseBefore)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/hashicorp/packer/hcl2template/internal"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
|
@ -122,6 +123,139 @@ func TestParse_build(t *testing.T) {
|
|||
[]packer.Build{},
|
||||
true,
|
||||
},
|
||||
{"post-processor with only and except",
|
||||
defaultParser,
|
||||
parseTestArgs{"testdata/build/post-processor_onlyexcept.pkr.hcl", nil, nil},
|
||||
&PackerConfig{
|
||||
Basedir: filepath.Join("testdata", "build"),
|
||||
Sources: map[SourceRef]SourceBlock{
|
||||
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
|
||||
refAWSEBSUbuntu1604: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
||||
},
|
||||
Builds: Builds{
|
||||
&BuildBlock{
|
||||
Sources: []SourceRef{refVBIsoUbuntu1204, refAWSEBSUbuntu1604},
|
||||
ProvisionerBlocks: nil,
|
||||
PostProcessors: []*PostProcessorBlock{
|
||||
{
|
||||
PType: "amazon-import",
|
||||
OnlyExcept: OnlyExcept{Only: []string{"virtualbox-iso.ubuntu-1204"}, Except: nil},
|
||||
},
|
||||
{
|
||||
PType: "manifest",
|
||||
OnlyExcept: OnlyExcept{Only: nil, Except: []string{"virtualbox-iso.ubuntu-1204"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false, false,
|
||||
[]packer.Build{
|
||||
&packer.CoreBuild{
|
||||
Type: "virtualbox-iso.ubuntu-1204",
|
||||
Prepared: true,
|
||||
Builder: emptyMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{},
|
||||
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
||||
{
|
||||
{
|
||||
PType: "amazon-import",
|
||||
PostProcessor: &MockPostProcessor{
|
||||
Config: MockConfig{
|
||||
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
|
||||
NestedSlice: []NestedMockConfig{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&packer.CoreBuild{
|
||||
Type: "amazon-ebs.ubuntu-1604",
|
||||
Prepared: true,
|
||||
Builder: emptyMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{},
|
||||
PostProcessors: [][]packer.CoreBuildPostProcessor{
|
||||
{
|
||||
{
|
||||
PType: "manifest",
|
||||
PostProcessor: &MockPostProcessor{
|
||||
Config: MockConfig{
|
||||
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
|
||||
NestedSlice: []NestedMockConfig{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"provisioner with only and except",
|
||||
defaultParser,
|
||||
parseTestArgs{"testdata/build/provisioner_onlyexcept.pkr.hcl", nil, nil},
|
||||
&PackerConfig{
|
||||
Basedir: filepath.Join("testdata", "build"),
|
||||
Sources: map[SourceRef]SourceBlock{
|
||||
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
|
||||
refAWSEBSUbuntu1604: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
||||
},
|
||||
Builds: Builds{
|
||||
&BuildBlock{
|
||||
Sources: []SourceRef{refVBIsoUbuntu1204, refAWSEBSUbuntu1604},
|
||||
ProvisionerBlocks: []*ProvisionerBlock{
|
||||
{
|
||||
PType: "shell",
|
||||
OnlyExcept: OnlyExcept{Only: []string{"virtualbox-iso.ubuntu-1204"}, Except: nil},
|
||||
},
|
||||
{
|
||||
PType: "file",
|
||||
OnlyExcept: OnlyExcept{Only: nil, Except: []string{"virtualbox-iso.ubuntu-1204"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
false, false,
|
||||
[]packer.Build{
|
||||
&packer.CoreBuild{
|
||||
Type: "virtualbox-iso.ubuntu-1204",
|
||||
Prepared: true,
|
||||
Builder: emptyMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{
|
||||
{
|
||||
PType: "shell",
|
||||
Provisioner: &MockProvisioner{
|
||||
Config: MockConfig{
|
||||
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
|
||||
NestedSlice: []NestedMockConfig{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
PostProcessors: [][]packer.CoreBuildPostProcessor{},
|
||||
},
|
||||
&packer.CoreBuild{
|
||||
Type: "amazon-ebs.ubuntu-1604",
|
||||
Prepared: true,
|
||||
Builder: emptyMockBuilder,
|
||||
Provisioners: []packer.CoreBuildProvisioner{
|
||||
{
|
||||
PType: "file",
|
||||
Provisioner: &MockProvisioner{
|
||||
Config: MockConfig{
|
||||
NestedMockConfig: NestedMockConfig{Tags: []MockTag{}},
|
||||
NestedSlice: []NestedMockConfig{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
PostProcessors: [][]packer.CoreBuildPostProcessor{},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
testParse(t, tests)
|
||||
}
|
||||
|
|
|
@ -198,6 +198,9 @@ func (cfg *PackerConfig) getCoreBuildProvisioners(source SourceBlock, blocks []*
|
|||
var diags hcl.Diagnostics
|
||||
res := []packer.CoreBuildProvisioner{}
|
||||
for _, pb := range blocks {
|
||||
if pb.OnlyExcept.Skip(source.Type + "." + source.Name) {
|
||||
continue
|
||||
}
|
||||
provisioner, moreDiags := cfg.startProvisioner(source, pb, ectx, generatedVars)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
|
@ -238,6 +241,9 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceBlock, blocks [
|
|||
var diags hcl.Diagnostics
|
||||
res := []packer.CoreBuildPostProcessor{}
|
||||
for _, ppb := range blocks {
|
||||
if ppb.OnlyExcept.Skip(source.Type + "." + source.Name) {
|
||||
continue
|
||||
}
|
||||
postProcessor, moreDiags := cfg.startPostProcessor(source, ppb, ectx, generatedVars)
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
var (
|
||||
refVBIsoUbuntu1204 = SourceRef{Type: "virtualbox-iso", Name: "ubuntu-1204"}
|
||||
refAWSEBSUbuntu1204 = SourceRef{Type: "amazon-ebs", Name: "ubuntu-1604"}
|
||||
refAWSEBSUbuntu1604 = SourceRef{Type: "amazon-ebs", Name: "ubuntu-1604"}
|
||||
)
|
||||
|
||||
func TestParser_complete(t *testing.T) {
|
||||
|
@ -73,13 +73,13 @@ func TestParser_complete(t *testing.T) {
|
|||
},
|
||||
Sources: map[SourceRef]SourceBlock{
|
||||
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
|
||||
refAWSEBSUbuntu1204: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
||||
refAWSEBSUbuntu1604: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
||||
},
|
||||
Builds: Builds{
|
||||
&BuildBlock{
|
||||
Sources: []SourceRef{
|
||||
refVBIsoUbuntu1204,
|
||||
refAWSEBSUbuntu1204,
|
||||
refAWSEBSUbuntu1604,
|
||||
},
|
||||
ProvisionerBlocks: []*ProvisionerBlock{
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue