Merge pull request #7183 from hashicorp/skip_post_processor
allow to use `-except` on post-processors
This commit is contained in:
commit
270f851e72
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/packer/builder/file"
|
"github.com/hashicorp/packer/builder/file"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
|
shell_local "github.com/hashicorp/packer/post-processor/shell-local"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBuildOnlyFileCommaFlags(t *testing.T) {
|
func TestBuildOnlyFileCommaFlags(t *testing.T) {
|
||||||
|
@ -26,12 +27,13 @@ func TestBuildOnlyFileCommaFlags(t *testing.T) {
|
||||||
fatalCommand(t, c.Meta)
|
fatalCommand(t, c.Meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fileExists("chocolate.txt") {
|
for _, f := range []string{"chocolate.txt", "vanilla.txt",
|
||||||
t.Error("Expected to find chocolate.txt")
|
"apple.txt", "peach.txt", "pear.txt"} {
|
||||||
}
|
if !fileExists(f) {
|
||||||
if !fileExists("vanilla.txt") {
|
t.Errorf("Expected to find %s", f)
|
||||||
t.Error("Expected to find vanilla.txt")
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileExists("cherry.txt") {
|
if fileExists("cherry.txt") {
|
||||||
t.Error("Expected NOT to find cherry.txt")
|
t.Error("Expected NOT to find cherry.txt")
|
||||||
}
|
}
|
||||||
|
@ -56,14 +58,10 @@ func TestBuildStdin(t *testing.T) {
|
||||||
fatalCommand(t, c.Meta)
|
fatalCommand(t, c.Meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fileExists("chocolate.txt") {
|
for _, f := range []string{"vanilla.txt", "cherry.txt", "chocolate.txt"} {
|
||||||
t.Error("Expected to find chocolate.txt")
|
if !fileExists(f) {
|
||||||
}
|
t.Errorf("Expected to find %s", f)
|
||||||
if !fileExists("vanilla.txt") {
|
}
|
||||||
t.Error("Expected to find vanilla.txt")
|
|
||||||
}
|
|
||||||
if !fileExists("cherry.txt") {
|
|
||||||
t.Error("Expected to find cherry.txt")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +73,9 @@ func TestBuildOnlyFileMultipleFlags(t *testing.T) {
|
||||||
args := []string{
|
args := []string{
|
||||||
"-only=chocolate",
|
"-only=chocolate",
|
||||||
"-only=cherry",
|
"-only=cherry",
|
||||||
|
"-only=apple", // ignored
|
||||||
|
"-only=peach", // ignored
|
||||||
|
"-only=pear", // ignored
|
||||||
filepath.Join(testFixture("build-only"), "template.json"),
|
filepath.Join(testFixture("build-only"), "template.json"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +85,16 @@ func TestBuildOnlyFileMultipleFlags(t *testing.T) {
|
||||||
fatalCommand(t, c.Meta)
|
fatalCommand(t, c.Meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fileExists("chocolate.txt") {
|
for _, f := range []string{"vanilla.txt"} {
|
||||||
t.Error("Expected to find chocolate.txt")
|
if fileExists(f) {
|
||||||
|
t.Errorf("Expected NOT to find %s", f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if fileExists("vanilla.txt") {
|
for _, f := range []string{"chocolate.txt", "cherry.txt",
|
||||||
t.Error("Expected NOT to find vanilla.txt")
|
"apple.txt", "peach.txt", "pear.txt"} {
|
||||||
}
|
if !fileExists(f) {
|
||||||
if !fileExists("cherry.txt") {
|
t.Errorf("Expected to find %s", f)
|
||||||
t.Error("Expected to find cherry.txt")
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +104,7 @@ func TestBuildExceptFileCommaFlags(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-except=chocolate",
|
"-except=chocolate,apple",
|
||||||
filepath.Join(testFixture("build-only"), "template.json"),
|
filepath.Join(testFixture("build-only"), "template.json"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,14 +114,15 @@ func TestBuildExceptFileCommaFlags(t *testing.T) {
|
||||||
fatalCommand(t, c.Meta)
|
fatalCommand(t, c.Meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fileExists("chocolate.txt") {
|
for _, f := range []string{"chocolate.txt", "apple.txt", "peach.txt"} {
|
||||||
t.Error("Expected NOT to find chocolate.txt")
|
if fileExists(f) {
|
||||||
|
t.Errorf("Expected NOT to find %s", f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !fileExists("vanilla.txt") {
|
for _, f := range []string{"vanilla.txt", "cherry.txt", "pear.txt"} {
|
||||||
t.Error("Expected to find vanilla.txt")
|
if !fileExists(f) {
|
||||||
}
|
t.Errorf("Expected to find %s", f)
|
||||||
if !fileExists("cherry.txt") {
|
}
|
||||||
t.Error("Expected to find cherry.txt")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +141,9 @@ func testCoreConfigBuilder(t *testing.T) *packer.CoreConfig {
|
||||||
Builder: func(n string) (packer.Builder, error) {
|
Builder: func(n string) (packer.Builder, error) {
|
||||||
return &file.Builder{}, nil
|
return &file.Builder{}, nil
|
||||||
},
|
},
|
||||||
|
PostProcessor: func(n string) (packer.PostProcessor, error) {
|
||||||
|
return &shell_local.PostProcessor{}, nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return &packer.CoreConfig{
|
return &packer.CoreConfig{
|
||||||
Components: components,
|
Components: components,
|
||||||
|
@ -159,4 +166,7 @@ func cleanup() {
|
||||||
os.RemoveAll("chocolate.txt")
|
os.RemoveAll("chocolate.txt")
|
||||||
os.RemoveAll("vanilla.txt")
|
os.RemoveAll("vanilla.txt")
|
||||||
os.RemoveAll("cherry.txt")
|
os.RemoveAll("cherry.txt")
|
||||||
|
os.RemoveAll("apple.txt")
|
||||||
|
os.RemoveAll("peach.txt")
|
||||||
|
os.RemoveAll("pear.txt")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/helper/flag-kv"
|
kvflag "github.com/hashicorp/packer/helper/flag-kv"
|
||||||
"github.com/hashicorp/packer/helper/flag-slice"
|
sliceflag "github.com/hashicorp/packer/helper/flag-slice"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template"
|
"github.com/hashicorp/packer/template"
|
||||||
)
|
)
|
||||||
|
@ -31,9 +31,7 @@ type Meta struct {
|
||||||
Version string
|
Version string
|
||||||
|
|
||||||
// These are set by command-line flags
|
// These are set by command-line flags
|
||||||
flagBuildExcept []string
|
flagVars map[string]string
|
||||||
flagBuildOnly []string
|
|
||||||
flagVars map[string]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Core returns the core for the given template given the configured
|
// Core returns the core for the given template given the configured
|
||||||
|
@ -59,7 +57,7 @@ func (m *Meta) BuildNames(c *packer.Core) []string {
|
||||||
// TODO: test
|
// TODO: test
|
||||||
|
|
||||||
// Filter the "only"
|
// Filter the "only"
|
||||||
if len(m.flagBuildOnly) > 0 {
|
if len(m.CoreConfig.Only) > 0 {
|
||||||
// Build a set of all the available names
|
// Build a set of all the available names
|
||||||
nameSet := make(map[string]struct{})
|
nameSet := make(map[string]struct{})
|
||||||
for _, n := range c.BuildNames() {
|
for _, n := range c.BuildNames() {
|
||||||
|
@ -67,8 +65,8 @@ func (m *Meta) BuildNames(c *packer.Core) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build our result set which we pre-allocate some sane number
|
// Build our result set which we pre-allocate some sane number
|
||||||
result := make([]string, 0, len(m.flagBuildOnly))
|
result := make([]string, 0, len(m.CoreConfig.Only))
|
||||||
for _, n := range m.flagBuildOnly {
|
for _, n := range m.CoreConfig.Only {
|
||||||
if _, ok := nameSet[n]; ok {
|
if _, ok := nameSet[n]; ok {
|
||||||
result = append(result, n)
|
result = append(result, n)
|
||||||
}
|
}
|
||||||
|
@ -78,10 +76,10 @@ func (m *Meta) BuildNames(c *packer.Core) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter the "except"
|
// Filter the "except"
|
||||||
if len(m.flagBuildExcept) > 0 {
|
if len(m.CoreConfig.Except) > 0 {
|
||||||
// Build a set of the things we don't want
|
// Build a set of the things we don't want
|
||||||
nameSet := make(map[string]struct{})
|
nameSet := make(map[string]struct{})
|
||||||
for _, n := range m.flagBuildExcept {
|
for _, n := range m.CoreConfig.Except {
|
||||||
nameSet[n] = struct{}{}
|
nameSet[n] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +109,8 @@ func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet {
|
||||||
// FlagSetBuildFilter tells us to enable the settings for selecting
|
// FlagSetBuildFilter tells us to enable the settings for selecting
|
||||||
// builds we care about.
|
// builds we care about.
|
||||||
if fs&FlagSetBuildFilter != 0 {
|
if fs&FlagSetBuildFilter != 0 {
|
||||||
f.Var((*sliceflag.StringFlag)(&m.flagBuildExcept), "except", "")
|
f.Var((*sliceflag.StringFlag)(&m.CoreConfig.Except), "except", "")
|
||||||
f.Var((*sliceflag.StringFlag)(&m.flagBuildOnly), "only", "")
|
f.Var((*sliceflag.StringFlag)(&m.CoreConfig.Only), "only", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlagSetVars tells us what variables to use
|
// FlagSetVars tells us what variables to use
|
||||||
|
|
|
@ -1,22 +1,43 @@
|
||||||
{
|
{
|
||||||
"builders": [
|
"builders": [
|
||||||
{
|
{
|
||||||
"name":"chocolate",
|
"name": "chocolate",
|
||||||
"type":"file",
|
"type": "file",
|
||||||
"content":"chocolate",
|
"content": "chocolate",
|
||||||
"target":"chocolate.txt"
|
"target": "chocolate.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"vanilla",
|
"name": "vanilla",
|
||||||
"type":"file",
|
"type": "file",
|
||||||
"content":"vanilla",
|
"content": "vanilla",
|
||||||
"target":"vanilla.txt"
|
"target": "vanilla.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"cherry",
|
"name": "cherry",
|
||||||
"type":"file",
|
"type": "file",
|
||||||
"content":"cherry",
|
"content": "cherry",
|
||||||
"target":"cherry.txt"
|
"target": "cherry.txt"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"post-processors": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple",
|
||||||
|
"type": "shell-local",
|
||||||
|
"inline": [ "touch apple.txt" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "peach",
|
||||||
|
"type": "shell-local",
|
||||||
|
"inline": [ "touch peach.txt" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "pear",
|
||||||
|
"type": "shell-local",
|
||||||
|
"inline": [ "touch pear.txt" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@ _packer () {
|
||||||
'-force[Force a build to continue if artifacts exist, deletes existing artifacts.]'
|
'-force[Force a build to continue if artifacts exist, deletes existing artifacts.]'
|
||||||
'-machine-readable[Produce machine-readable output.]'
|
'-machine-readable[Produce machine-readable output.]'
|
||||||
'-color=[(false) Disable color output. (Default: color)]'
|
'-color=[(false) Disable color output. (Default: color)]'
|
||||||
'-except=[(foo,bar,baz) Build all builds other than these.]'
|
'-except=[(foo,bar,baz) Run all builds and post-procesors other than these.]'
|
||||||
'-on-error=[(cleanup,abort,ask) If the build fails do: clean up (default), abort, or ask.]'
|
'-on-error=[(cleanup,abort,ask) If the build fails do: clean up (default), abort, or ask.]'
|
||||||
'-only=[(foo,bar,baz) Only build the given builds by name.]'
|
'-only=[(foo,bar,baz) Only build the given builds by name.]'
|
||||||
'-parallel=[(false) Disable parallelization. (Default: parallel)]'
|
'-parallel=[(false) Disable parallelization. (Default: parallel)]'
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/go-version"
|
version "github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/packer/template"
|
"github.com/hashicorp/packer/template"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,9 @@ type Core struct {
|
||||||
builds map[string]*template.Builder
|
builds map[string]*template.Builder
|
||||||
version string
|
version string
|
||||||
secrets []string
|
secrets []string
|
||||||
|
|
||||||
|
except []string
|
||||||
|
only []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig
|
// CoreConfig is the structure for initializing a new Core. Once a CoreConfig
|
||||||
|
@ -30,6 +33,10 @@ type CoreConfig struct {
|
||||||
Variables map[string]string
|
Variables map[string]string
|
||||||
SensitiveVariables []string
|
SensitiveVariables []string
|
||||||
Version string
|
Version string
|
||||||
|
|
||||||
|
// These are set by command-line flags
|
||||||
|
Except []string
|
||||||
|
Only []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// The function type used to lookup Builder implementations.
|
// The function type used to lookup Builder implementations.
|
||||||
|
@ -61,6 +68,8 @@ func NewCore(c *CoreConfig) (*Core, error) {
|
||||||
components: c.Components,
|
components: c.Components,
|
||||||
variables: c.Variables,
|
variables: c.Variables,
|
||||||
version: c.Version,
|
version: c.Version,
|
||||||
|
only: c.Only,
|
||||||
|
except: c.Except,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := result.validate(); err != nil {
|
if err := result.validate(); err != nil {
|
||||||
|
@ -126,7 +135,7 @@ func (c *Core) Build(n string) (Build, error) {
|
||||||
provisioners := make([]coreBuildProvisioner, 0, len(c.Template.Provisioners))
|
provisioners := make([]coreBuildProvisioner, 0, len(c.Template.Provisioners))
|
||||||
for _, rawP := range c.Template.Provisioners {
|
for _, rawP := range c.Template.Provisioners {
|
||||||
// If we're skipping this, then ignore it
|
// If we're skipping this, then ignore it
|
||||||
if rawP.Skip(rawName) {
|
if rawP.OnlyExcept.Skip(rawName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,9 +181,13 @@ func (c *Core) Build(n string) (Build, error) {
|
||||||
current := make([]coreBuildPostProcessor, 0, len(rawPs))
|
current := make([]coreBuildPostProcessor, 0, len(rawPs))
|
||||||
for _, rawP := range rawPs {
|
for _, rawP := range rawPs {
|
||||||
// If we skip, ignore
|
// If we skip, ignore
|
||||||
if rawP.Skip(rawName) {
|
rawP.OnlyExcept.Except = append(rawP.OnlyExcept.Except, c.except...)
|
||||||
|
if rawP.OnlyExcept.Skip(rawName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if rawP.OnlyExcept.Skip(rawP.Name) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Get the post-processor
|
// Get the post-processor
|
||||||
postProcessor, err := c.components.PostProcessor(rawP.Type)
|
postProcessor, err := c.components.PostProcessor(rawP.Type)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/packer/packer/tmp"
|
"github.com/hashicorp/packer/packer/tmp"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
)
|
)
|
||||||
|
@ -149,6 +149,7 @@ func (r *rawTemplate) Template() (*Template, error) {
|
||||||
delete(c, "only")
|
delete(c, "only")
|
||||||
delete(c, "keep_input_artifact")
|
delete(c, "keep_input_artifact")
|
||||||
delete(c, "type")
|
delete(c, "type")
|
||||||
|
delete(c, "name")
|
||||||
if len(c) > 0 {
|
if len(c) > 0 {
|
||||||
pp.Config = c
|
pp.Config = c
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Template represents the parsed template that is used to configure
|
// Template represents the parsed template that is used to configure
|
||||||
|
@ -40,6 +40,7 @@ type Builder struct {
|
||||||
type PostProcessor struct {
|
type PostProcessor struct {
|
||||||
OnlyExcept `mapstructure:",squash"`
|
OnlyExcept `mapstructure:",squash"`
|
||||||
|
|
||||||
|
Name string
|
||||||
Type string
|
Type string
|
||||||
KeepInputArtifact bool `mapstructure:"keep_input_artifact"`
|
KeepInputArtifact bool `mapstructure:"keep_input_artifact"`
|
||||||
Config map[string]interface{}
|
Config map[string]interface{}
|
||||||
|
|
|
@ -26,10 +26,12 @@ artifacts that are created will be outputted at the end of the build.
|
||||||
will stop between each step, waiting for keyboard input before continuing.
|
will stop between each step, waiting for keyboard input before continuing.
|
||||||
This will allow the user to inspect state and so on.
|
This will allow the user to inspect state and so on.
|
||||||
|
|
||||||
- `-except=foo,bar,baz` - Builds all the builds except those with the given
|
- `-except=foo,bar,baz` - Run all the builds and post-processors except those
|
||||||
comma-separated names. Build names by default are the names of their
|
with the given comma-separated names. Build and post-processor names by
|
||||||
builders, unless a specific `name` attribute is specified within the
|
default are their type, unless a specific `name` attribute is specified
|
||||||
configuration.
|
within the configuration. Any post-processor following a skipped
|
||||||
|
post-processor will not run. Because post-processors can be nested in
|
||||||
|
arrays a differ post-processor chain can still run.
|
||||||
|
|
||||||
- `-force` - Forces a builder to run when artifacts from a previous build
|
- `-force` - Forces a builder to run when artifacts from a previous build
|
||||||
prevent a build from running. The exact behavior of a forced build is left
|
prevent a build from running. The exact behavior of a forced build is left
|
||||||
|
@ -44,9 +46,10 @@ artifacts that are created will be outputted at the end of the build.
|
||||||
presents a prompt and waits for you to decide to clean up, abort, or retry
|
presents a prompt and waits for you to decide to clean up, abort, or retry
|
||||||
the failed step.
|
the failed step.
|
||||||
|
|
||||||
- `-only=foo,bar,baz` - Only build the builds with the given comma-separated
|
- `-only=foo,bar,baz` - Only run the builds with the given comma-separated
|
||||||
names. Build names by default are the names of their builders, unless a
|
names. Build names by default are their type, unless a specific `name`
|
||||||
specific `name` attribute is specified within the configuration.
|
attribute is specified within the configuration. `-only` does not apply to
|
||||||
|
post-processors.
|
||||||
|
|
||||||
- `-parallel=false` - Disable parallelization of multiple builders (on by
|
- `-parallel=false` - Disable parallelization of multiple builders (on by
|
||||||
default).
|
default).
|
||||||
|
|
|
@ -81,6 +81,7 @@ The values within `only` or `except` are *build names*, not builder types. If
|
||||||
you recall, build names by default are just their builder type, but if you
|
you recall, build names by default are just their builder type, but if you
|
||||||
specify a custom `name` parameter, then you should use that as the value
|
specify a custom `name` parameter, then you should use that as the value
|
||||||
instead of the type.
|
instead of the type.
|
||||||
|
Values within `except` could also be a *post-processor* name.
|
||||||
|
|
||||||
## Build-Specific Overrides
|
## Build-Specific Overrides
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue