Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: only/except validation after interpolation #4508

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packer/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func NewCore(c *CoreConfig) (*Core, error) {
result.builds[v] = b
}

if err := result.postRenderValidate(); err != nil {
return nil, err
}

return result, nil
}

Expand Down Expand Up @@ -219,6 +223,10 @@ func (c *Core) Context() *interpolate.Context {
}
}

func (c *Core) postRenderValidate() error {
return c.Template.OnlyExceptValidate(c.builds)
}

// validate does a full validation of the template.
//
// This will automatically call template.validate() in addition to doing
Expand Down
22 changes: 12 additions & 10 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,21 @@ type OnlyExcept struct {
// are the minimal necessary to make sure parsing builds a reasonable
// Template structure.
func (t *Template) Validate() error {
var err error

// At least one builder must be defined
if len(t.Builders) == 0 {
err = multierror.Append(err, errors.New(
"at least one builder must be defined"))
return errors.New("at least one builder must be defined")
}

return nil
}

func (t *Template) OnlyExceptValidate(builds map[string]*Builder) error {

var err error
// Verify that the provisioner overrides target builders that exist
for i, p := range t.Provisioners {
// Validate only/except
if verr := p.OnlyExcept.Validate(t); verr != nil {
if verr := p.OnlyExcept.Validate(builds); verr != nil {
for _, e := range multierror.Append(verr).Errors {
err = multierror.Append(err, fmt.Errorf(
"provisioner %d: %s", i+1, e))
Expand All @@ -120,15 +123,14 @@ func (t *Template) Validate() error {
for i, chain := range t.PostProcessors {
for j, p := range chain {
// Validate only/except
if verr := p.OnlyExcept.Validate(t); verr != nil {
if verr := p.OnlyExcept.Validate(builds); verr != nil {
for _, e := range multierror.Append(verr).Errors {
err = multierror.Append(err, fmt.Errorf(
"post-processor %d.%d: %s", i+1, j+1, e))
}
}
}
}

return err
}

Expand Down Expand Up @@ -158,20 +160,20 @@ func (o *OnlyExcept) Skip(n string) bool {
}

// Validate validates that the OnlyExcept settings are correct for a thing.
func (o *OnlyExcept) Validate(t *Template) error {
func (o *OnlyExcept) Validate(builds map[string]*Builder) error {
if len(o.Only) > 0 && len(o.Except) > 0 {
return errors.New("only one of 'only' or 'except' may be specified")
}

var err error
for _, n := range o.Only {
if _, ok := t.Builders[n]; !ok {
if _, ok := builds[n]; !ok {
err = multierror.Append(err, fmt.Errorf(
"'only' specified builder '%s' not found", n))
}
}
for _, n := range o.Except {
if _, ok := t.Builders[n]; !ok {
if _, ok := builds[n]; !ok {
err = multierror.Append(err, fmt.Errorf(
"'except' specified builder '%s' not found", n))
}
Expand Down