packer/plugin: Much more robust subprocess starting
This commit is contained in:
parent
86f1fbe925
commit
0cc3a5f918
|
@ -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 {
|
||||||
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 packrpc.Command(client)
|
||||||
return realCommand.Synopsis()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Command(cmd *exec.Cmd) packer.Command {
|
|
||||||
return &processCommand{cmd}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
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 (
|
||||||
"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 {
|
||||||
|
|
Loading…
Reference in New Issue