command/validate: validates templates

This commit is contained in:
Mitchell Hashimoto 2013-06-13 10:03:44 -07:00
parent d6b0ff6a7f
commit 0b896a0ce2
4 changed files with 115 additions and 1 deletions

View File

@ -0,0 +1,87 @@
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"
}

16
command/validate/help.go Normal file
View File

@ -0,0 +1,16 @@
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.
`

View File

@ -23,7 +23,8 @@ const defaultConfig = `
},
"commands": {
"build": "packer-command-build"
"build": "packer-command-build",
"validate": "packer-command-validate"
},
"provisioners": {

View File

@ -0,0 +1,10 @@
package main
import (
"github.com/mitchellh/packer/command/validate"
"github.com/mitchellh/packer/packer/plugin"
)
func main() {
plugin.ServeCommand(new(validate.Command))
}