command/validate: validates templates
This commit is contained in:
parent
d6b0ff6a7f
commit
0b896a0ce2
|
@ -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"
|
||||
}
|
|
@ -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.
|
||||
`
|
|
@ -23,7 +23,8 @@ const defaultConfig = `
|
|||
},
|
||||
|
||||
"commands": {
|
||||
"build": "packer-command-build"
|
||||
"build": "packer-command-build",
|
||||
"validate": "packer-command-validate"
|
||||
},
|
||||
|
||||
"provisioners": {
|
||||
|
|
|
@ -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))
|
||||
}
|
Loading…
Reference in New Issue