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