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

packer/plugin: Much more robust subprocess starting

parent 86f1fbe9
...@@ -10,19 +10,10 @@ import ( ...@@ -10,19 +10,10 @@ import (
"time" "time"
) )
type processCommand struct { func Command(cmd *exec.Cmd) packer.Command {
cmd *exec.Cmd
}
func (c *processCommand) Run(e packer.Environment, args []string) int {
return 0
}
func (c *processCommand) Synopsis() string {
out := new(bytes.Buffer) out := new(bytes.Buffer)
c.cmd.Stdout = out cmd.Stdout = out
c.cmd.Start() cmd.Start()
defer c.cmd.Process.Kill()
// TODO: timeout // TODO: timeout
// TODO: check that command is even running // TODO: check that command is even running
...@@ -37,13 +28,10 @@ func (c *processCommand) Synopsis() string { ...@@ -37,13 +28,10 @@ func (c *processCommand) Synopsis() string {
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
} }
client, _ := rpc.Dial("tcp", address) client, err := rpc.Dial("tcp", address)
defer client.Close() if err != nil {
panic(err)
realCommand := packrpc.Command(client) }
return realCommand.Synopsis()
}
func Command(cmd *exec.Cmd) packer.Command { return packrpc.Command(client)
return &processCommand{cmd}
} }
...@@ -6,26 +6,42 @@ package plugin ...@@ -6,26 +6,42 @@ package plugin
import ( import (
"fmt" "fmt"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"net"
"net/rpc"
"os" "os"
packrpc "github.com/mitchellh/packer/packer/rpc" packrpc "github.com/mitchellh/packer/packer/rpc"
) )
// This serves the plugin by starting the RPC server and serving requests. // This serves a single RPC connection on the given RPC server on
// This function never returns. // a random port.
func serve(server *packrpc.Server) { func serve(server *rpc.Server) (err error) {
// Start up the server listener, err := net.Listen("tcp", ":2345")
server.Start() if err != nil {
return
}
defer listener.Close()
// Output the address to stdout // Output the address to stdout
fmt.Println(server.Address()) fmt.Println(":2345")
os.Stdout.Sync() os.Stdout.Sync()
// Never return, wait on a channel that never gets a message // Accept a connection
<-make(chan bool) conn, err := listener.Accept()
if err != nil {
return
}
// Serve a single connection
server.ServeConn(conn)
return
} }
// Serves a command from a plugin.
func ServeCommand(command packer.Command) { func ServeCommand(command packer.Command) {
server := packrpc.NewServer() server := rpc.NewServer()
server.RegisterCommand(command) packrpc.RegisterCommand(server, command)
serve(server)
if err := serve(server); err != nil {
panic(err)
}
} }
...@@ -31,12 +31,20 @@ func Command(client *rpc.Client) *ClientCommand { ...@@ -31,12 +31,20 @@ func Command(client *rpc.Client) *ClientCommand {
func (c *ClientCommand) Run(env packer.Environment, args []string) (result int) { func (c *ClientCommand) Run(env packer.Environment, args []string) (result int) {
// TODO: Environment // TODO: Environment
rpcArgs := &CommandRunArgs{nil, args} rpcArgs := &CommandRunArgs{nil, args}
c.client.Call("Command.Run", rpcArgs, &result) err := c.client.Call("Command.Run", rpcArgs, &result)
if err != nil {
panic(err)
}
return return
} }
func (c *ClientCommand) Synopsis() (result string) { func (c *ClientCommand) Synopsis() (result string) {
c.client.Call("Command.Synopsis", CommandSynopsisArgs(0), &result) err := c.client.Call("Command.Synopsis", CommandSynopsisArgs(0), &result)
if err != nil {
panic(err)
}
return return
} }
......
...@@ -7,6 +7,10 @@ import ( ...@@ -7,6 +7,10 @@ import (
"net/rpc" "net/rpc"
) )
func RegisterCommand(s *rpc.Server, c packer.Command) {
s.RegisterName("Command", &ServerCommand{c})
}
// A Server is a Golang RPC server that has helper methods for automatically // A Server is a Golang RPC server that has helper methods for automatically
// setting up the endpoints for Packer interfaces. // setting up the endpoints for Packer interfaces.
type Server struct { type Server struct {
......
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