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{
|
PostProcessorsSchemas: packer.MapOfPostProcessor{
|
||||||
"amazon-import": func() (packer.PostProcessor, error) { return &MockPostProcessor{}, nil },
|
"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
|
// ProvisionerBlock references a detected but unparsed post processor
|
||||||
type PostProcessorBlock struct {
|
type PostProcessorBlock struct {
|
||||||
PType string
|
PType string
|
||||||
PName string
|
PName string
|
||||||
|
OnlyExcept OnlyExcept
|
||||||
|
|
||||||
HCL2Ref
|
HCL2Ref
|
||||||
}
|
}
|
||||||
|
@ -22,8 +23,10 @@ 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"`
|
||||||
Rest hcl.Body `hcl:",remain"`
|
Only []string `hcl:"only,optional"`
|
||||||
|
Except []string `hcl:"except,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() {
|
||||||
|
@ -31,9 +34,15 @@ 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,
|
||||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
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) {
|
if !p.PostProcessorsSchemas.Has(postProcessor.PType) {
|
||||||
|
|
|
@ -9,6 +9,52 @@ import (
|
||||||
"github.com/hashicorp/packer/packer"
|
"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
|
// ProvisionerBlock references a detected but unparsed provisioner
|
||||||
type ProvisionerBlock struct {
|
type ProvisionerBlock struct {
|
||||||
PType string
|
PType string
|
||||||
|
@ -16,6 +62,7 @@ type ProvisionerBlock struct {
|
||||||
PauseBefore time.Duration
|
PauseBefore time.Duration
|
||||||
MaxRetries int
|
MaxRetries int
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
|
OnlyExcept OnlyExcept
|
||||||
HCL2Ref
|
HCL2Ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +76,8 @@ func (p *Parser) decodeProvisioner(block *hcl.Block) (*ProvisionerBlock, hcl.Dia
|
||||||
PauseBefore string `hcl:"pause_before,optional"`
|
PauseBefore string `hcl:"pause_before,optional"`
|
||||||
MaxRetries int `hcl:"max_retries,optional"`
|
MaxRetries int `hcl:"max_retries,optional"`
|
||||||
Timeout string `hcl:"timeout,optional"`
|
Timeout string `hcl:"timeout,optional"`
|
||||||
|
Only []string `hcl:"only,optional"`
|
||||||
|
Except []string `hcl:"except,optional"`
|
||||||
Rest hcl.Body `hcl:",remain"`
|
Rest hcl.Body `hcl:",remain"`
|
||||||
}
|
}
|
||||||
diags := gohcl.DecodeBody(block.Body, nil, &b)
|
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],
|
PType: block.Labels[0],
|
||||||
PName: b.Name,
|
PName: b.Name,
|
||||||
MaxRetries: b.MaxRetries,
|
MaxRetries: b.MaxRetries,
|
||||||
|
OnlyExcept: OnlyExcept{Only: b.Only, Except: b.Except},
|
||||||
HCL2Ref: newHCL2Ref(block, b.Rest),
|
HCL2Ref: newHCL2Ref(block, b.Rest),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diags = diags.Extend(provisioner.OnlyExcept.Validate())
|
||||||
|
if diags.HasErrors() {
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
if b.PauseBefore != "" {
|
if b.PauseBefore != "" {
|
||||||
pauseBefore, err := time.ParseDuration(b.PauseBefore)
|
pauseBefore, err := time.ParseDuration(b.PauseBefore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/hashicorp/packer/hcl2template/internal"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,6 +123,139 @@ func TestParse_build(t *testing.T) {
|
||||||
[]packer.Build{},
|
[]packer.Build{},
|
||||||
true,
|
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)
|
testParse(t, tests)
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,9 @@ func (cfg *PackerConfig) getCoreBuildProvisioners(source SourceBlock, blocks []*
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
res := []packer.CoreBuildProvisioner{}
|
res := []packer.CoreBuildProvisioner{}
|
||||||
for _, pb := range blocks {
|
for _, pb := range blocks {
|
||||||
|
if pb.OnlyExcept.Skip(source.Type + "." + source.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
provisioner, moreDiags := cfg.startProvisioner(source, pb, ectx, generatedVars)
|
provisioner, moreDiags := cfg.startProvisioner(source, pb, ectx, generatedVars)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
|
@ -238,6 +241,9 @@ func (cfg *PackerConfig) getCoreBuildPostProcessors(source SourceBlock, blocks [
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
res := []packer.CoreBuildPostProcessor{}
|
res := []packer.CoreBuildPostProcessor{}
|
||||||
for _, ppb := range blocks {
|
for _, ppb := range blocks {
|
||||||
|
if ppb.OnlyExcept.Skip(source.Type + "." + source.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
postProcessor, moreDiags := cfg.startPostProcessor(source, ppb, ectx, generatedVars)
|
postProcessor, moreDiags := cfg.startPostProcessor(source, ppb, ectx, generatedVars)
|
||||||
diags = append(diags, moreDiags...)
|
diags = append(diags, moreDiags...)
|
||||||
if moreDiags.HasErrors() {
|
if moreDiags.HasErrors() {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
refVBIsoUbuntu1204 = SourceRef{Type: "virtualbox-iso", Name: "ubuntu-1204"}
|
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) {
|
func TestParser_complete(t *testing.T) {
|
||||||
|
@ -73,13 +73,13 @@ func TestParser_complete(t *testing.T) {
|
||||||
},
|
},
|
||||||
Sources: map[SourceRef]SourceBlock{
|
Sources: map[SourceRef]SourceBlock{
|
||||||
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
|
refVBIsoUbuntu1204: {Type: "virtualbox-iso", Name: "ubuntu-1204"},
|
||||||
refAWSEBSUbuntu1204: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
refAWSEBSUbuntu1604: {Type: "amazon-ebs", Name: "ubuntu-1604"},
|
||||||
},
|
},
|
||||||
Builds: Builds{
|
Builds: Builds{
|
||||||
&BuildBlock{
|
&BuildBlock{
|
||||||
Sources: []SourceRef{
|
Sources: []SourceRef{
|
||||||
refVBIsoUbuntu1204,
|
refVBIsoUbuntu1204,
|
||||||
refAWSEBSUbuntu1204,
|
refAWSEBSUbuntu1604,
|
||||||
},
|
},
|
||||||
ProvisionerBlocks: []*ProvisionerBlock{
|
ProvisionerBlocks: []*ProvisionerBlock{
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue