Lots of stuff, too early for meaningful commit messages
UI, command dispatch
This commit is contained in:
parent
817822abab
commit
db1c11fff5
|
@ -1,2 +1 @@
|
|||
/bin
|
||||
/packer
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
all:
|
||||
@mkdir -p bin/
|
||||
go get -a
|
||||
go get -d
|
||||
go build -a -o bin/packer
|
||||
|
||||
.PHONY: all
|
||||
|
|
|
@ -11,11 +11,12 @@ type Builder struct {
|
|||
config config
|
||||
}
|
||||
|
||||
func (b *Builder) ConfigInterface() interface{} {
|
||||
return &b.config
|
||||
}
|
||||
|
||||
func (*Builder) Prepare() {
|
||||
}
|
||||
|
||||
func (*Builder) Build() {
|
||||
}
|
||||
|
||||
func (*Builder) Destroy() {
|
||||
func (b *Builder) Build() {
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "my-custom-image",
|
||||
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"region": "us-east-1",
|
||||
"source": "ami-de0d9eb7"
|
||||
}
|
||||
],
|
||||
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "shell",
|
||||
"path": "script.sh"
|
||||
}
|
||||
],
|
||||
|
||||
"outputs": [
|
||||
{
|
||||
"type": "vagrant"
|
||||
}
|
||||
]
|
||||
}
|
56
packer.go
56
packer.go
|
@ -1,44 +1,40 @@
|
|||
// This is the main package for the `packer` application.
|
||||
package main
|
||||
|
||||
import "github.com/mitchellh/packer/builder/amazon"
|
||||
import "github.com/mitchellh/packer/packer"
|
||||
import "os"
|
||||
|
||||
// A command is a runnable sub-command of the `packer` application.
|
||||
// When `packer` is called with the proper subcommand, this will be
|
||||
// called.
|
||||
//
|
||||
// The mapping of command names to command interfaces is in the
|
||||
// Environment struct.
|
||||
type Command interface {
|
||||
Run(args []string)
|
||||
}
|
||||
|
||||
// The environment struct contains all the state necessary for a single
|
||||
// instance of Packer.
|
||||
//
|
||||
// It is *not* a singleton, but generally a single environment is created
|
||||
// when Packer starts running to represent that Packer run. Technically,
|
||||
// if you're building a custom Packer binary, you could instantiate multiple
|
||||
// environments and run them in parallel.
|
||||
type Environment struct {
|
||||
commands map[string]Command
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
type RawTemplate struct {
|
||||
Name string
|
||||
Builders map[string]interface{} `toml:"builder"`
|
||||
Provisioners map[string]interface{} `toml:"provision"`
|
||||
Outputs map[string]interface{} `toml:"output"`
|
||||
Builders []map[string]interface{}
|
||||
Provisioners []map[string]interface{}
|
||||
Outputs []map[string]interface{}
|
||||
}
|
||||
|
||||
type Builder interface {
|
||||
ConfigInterface() interface{}
|
||||
Prepare()
|
||||
Build()
|
||||
Destroy()
|
||||
}
|
||||
|
||||
type Build interface {
|
||||
Hook(name string)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var builder Builder
|
||||
builder = &amazon.Builder{}
|
||||
builder.Build()
|
||||
env := packer.NewEnvironment()
|
||||
os.Exit(env.Cli(os.Args[1:]))
|
||||
/*
|
||||
file, _ := ioutil.ReadFile("example.json")
|
||||
|
||||
var tpl RawTemplate
|
||||
json.Unmarshal(file, &tpl)
|
||||
fmt.Printf("%#v\n", tpl)
|
||||
|
||||
builderType, ok := tpl.Builders[0]["type"].(Build)
|
||||
if !ok {
|
||||
panic("OH NOES")
|
||||
}
|
||||
fmt.Printf("TYPE: %v\n", builderType)
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
// The packer package contains the core components of Packer.
|
||||
package packer
|
||||
|
||||
import "os"
|
||||
|
||||
// A command is a runnable sub-command of the `packer` application.
|
||||
// When `packer` is called with the proper subcommand, this will be
|
||||
// called.
|
||||
//
|
||||
// The mapping of command names to command interfaces is in the
|
||||
// Environment struct.
|
||||
type Command interface {
|
||||
Run(env *Environment, args []string) int
|
||||
}
|
||||
|
||||
// The environment struct contains all the state necessary for a single
|
||||
// instance of Packer.
|
||||
//
|
||||
// It is *not* a singleton, but generally a single environment is created
|
||||
// when Packer starts running to represent that Packer run. Technically,
|
||||
// if you're building a custom Packer binary, you could instantiate multiple
|
||||
// environments and run them in parallel.
|
||||
type Environment struct {
|
||||
command map[string]Command
|
||||
ui Ui
|
||||
}
|
||||
|
||||
// This creates a new environment
|
||||
func NewEnvironment() *Environment {
|
||||
env := &Environment{}
|
||||
env.command = make(map[string]Command)
|
||||
env.command["version"] = new(versionCommand)
|
||||
env.ui = &ReaderWriterUi{ os.Stdin, os.Stdout }
|
||||
return env
|
||||
}
|
||||
|
||||
// Executes a command as if it was typed on the command-line interface.
|
||||
// The return value is the exit code of the command.
|
||||
func (e *Environment) Cli(args []string) int {
|
||||
if len(args) == 0 {
|
||||
e.PrintHelp()
|
||||
return 1
|
||||
}
|
||||
|
||||
command, ok := e.command[args[0]]
|
||||
if !ok {
|
||||
// The command was not found. In this case, let's go through
|
||||
// the arguments and see if the user is requesting the version.
|
||||
for _, arg := range args {
|
||||
if arg == "--version" || arg == "-v" {
|
||||
command = e.command["version"]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If we still don't have a command, show the help.
|
||||
if command == nil {
|
||||
e.PrintHelp()
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return command.Run(e, args)
|
||||
}
|
||||
|
||||
// Returns the UI for the environment. The UI is the interface that should
|
||||
// be used for all communication with the outside world.
|
||||
func (e *Environment) Ui() Ui {
|
||||
return e.ui
|
||||
}
|
||||
|
||||
// Prints the CLI help to the UI.
|
||||
func (e *Environment) PrintHelp() {
|
||||
e.ui.Say("Bad.\n")
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package packer
|
||||
|
||||
import "fmt"
|
||||
import "io"
|
||||
|
||||
// The Ui interface handles all communication for Packer with the outside
|
||||
// world. This sort of control allows us to strictly control how output
|
||||
// is formatted and various levels of output.
|
||||
type Ui interface {
|
||||
Say(format string, a ...interface{})
|
||||
}
|
||||
|
||||
// The ReaderWriterUi is a UI that writes and reads from standard Go
|
||||
// io.Reader and io.Writer.
|
||||
type ReaderWriterUi struct {
|
||||
Reader io.Reader
|
||||
Writer io.Writer
|
||||
}
|
||||
|
||||
func (rw *ReaderWriterUi) Say(format string, a ...interface{}) {
|
||||
fmt.Fprintf(rw.Writer, format, a...)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package packer
|
||||
|
||||
// The version of packer.
|
||||
const Version = "0.1.0.dev"
|
||||
|
||||
type versionCommand byte
|
||||
|
||||
// Implement the Command interface by simply showing the version
|
||||
func (versionCommand) Run(env *Environment, args[] string) int {
|
||||
env.Ui().Say("Packer v%v\n", Version)
|
||||
return 0
|
||||
}
|
Loading…
Reference in New Issue