Commit 0b896a0c authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

command/validate: validates templates

parent d6b0ff6a
package validate
import (
"flag"
"fmt"
"github.com/mitchellh/packer/packer"
"io/ioutil"
"log"
"strings"
)
type Command byte
func (Command) Help() string {
return strings.TrimSpace(helpString)
}
func (c Command) Run(env packer.Environment, args []string) int {
var cfgSyntaxOnly bool
cmdFlags := flag.NewFlagSet("validate", flag.ContinueOnError)
cmdFlags.Usage = func() { env.Ui().Say(c.Help()) }
cmdFlags.BoolVar(&cfgSyntaxOnly, "syntax-only", false, "check syntax only")
if err := cmdFlags.Parse(args); err != nil {
return 1
}
args = cmdFlags.Args()
if len(args) != 1 {
cmdFlags.Usage()
return 1
}
// Read the file into a byte array so that we can parse the template
log.Printf("Reading template: %s", args[0])
tplData, err := ioutil.ReadFile(args[0])
if err != nil {
env.Ui().Error(fmt.Sprintf("Failed to read template file: %s", err))
return 1
}
// Parse the template into a machine-usable format
log.Println("Parsing template...")
tpl, err := packer.ParseTemplate(tplData)
if err != nil {
env.Ui().Error(fmt.Sprintf("Failed to parse template: %s", err))
return 1
}
if cfgSyntaxOnly {
env.Ui().Say("Syntax-only check passed. Everything looks okay.")
return 0
}
errs := make([]error, 0)
// The component finder for our builds
components := &packer.ComponentFinder{
Builder: env.Builder,
Hook: env.Hook,
Provisioner: env.Provisioner,
}
// Otherwise, get all the builds
buildNames := tpl.BuildNames()
builds := make([]packer.Build, len(buildNames))
for i, buildName := range buildNames {
var err error
builds[i], err = tpl.Build(buildName, components)
if err != nil {
errs = append(errs, fmt.Errorf("Build '%s': %s", buildName, err))
}
}
if len(errs) > 0 {
err = &packer.MultiError{errs}
env.Ui().Error(fmt.Sprintf("Template validation failed. %s", err))
return 1
}
env.Ui().Say("Template validated successfully.")
return 0
}
func (Command) Synopsis() string {
return "check that a template is valid"
}
package validate
const helpString = `
Usage: packer validate TEMPLATE
Checks the template is valid by parsing the template and also
checking the configuration with the various builders, provisioners, etc.
If it is not valid, the errors will be shown and the command will exit
with a non-zero exit status. If it is valid, it will exit with a zero
exit status.
Options:
-syntax-only Only check syntax. Do not verify config of the template.
`
...@@ -23,7 +23,8 @@ const defaultConfig = ` ...@@ -23,7 +23,8 @@ const defaultConfig = `
}, },
"commands": { "commands": {
"build": "packer-command-build" "build": "packer-command-build",
"validate": "packer-command-validate"
}, },
"provisioners": { "provisioners": {
......
package main
import (
"github.com/mitchellh/packer/command/validate"
"github.com/mitchellh/packer/packer/plugin"
)
func main() {
plugin.ServeCommand(new(validate.Command))
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment