Commit 779b6d17 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer/rpc, packer/plugin: remove Command interfaces

parent 3e1f4ae1
......@@ -104,19 +104,6 @@ func (c *config) LoadBuilder(name string) (packer.Builder, error) {
return c.pluginClient(bin).Builder()
}
// This is a proper packer.CommandFunc that can be used to load packer.Command
// implementations from the defined plugins.
func (c *config) LoadCommand(name string) (packer.Command, error) {
log.Printf("Loading command: %s\n", name)
bin, ok := c.Commands[name]
if !ok {
log.Printf("Command not found: %s\n", name)
return nil, nil
}
return c.pluginClient(bin).Command()
}
// This is a proper implementation of packer.HookFunc that can be used
// to load packer.Hook implementations from the defined plugins.
func (c *config) LoadHook(name string) (packer.Hook, error) {
......
......@@ -138,17 +138,6 @@ func (c *Client) Builder() (packer.Builder, error) {
return &cmdBuilder{client.Builder(), c}, nil
}
// Returns a command implementation that is communicating over this
// client. If the client hasn't been started, this will start it.
func (c *Client) Command() (packer.Command, error) {
client, err := c.packrpcClient()
if err != nil {
return nil, err
}
return &cmdCommand{client.Command(), c}, nil
}
// Returns a hook implementation that is communicating over this
// client. If the client hasn't been started, this will start it.
func (c *Client) Hook() (packer.Hook, error) {
......
package plugin
import (
"github.com/mitchellh/packer/packer"
"log"
)
type cmdCommand struct {
command packer.Command
client *Client
}
func (c *cmdCommand) Help() (result string) {
defer func() {
r := recover()
c.checkExit(r, func() { result = "" })
}()
result = c.command.Help()
return
}
func (c *cmdCommand) Run(e packer.Environment, args []string) (exitCode int) {
defer func() {
r := recover()
c.checkExit(r, func() { exitCode = 1 })
}()
exitCode = c.command.Run(e, args)
return
}
func (c *cmdCommand) Synopsis() (result string) {
defer func() {
r := recover()
c.checkExit(r, func() {
result = ""
})
}()
result = c.command.Synopsis()
return
}
func (c *cmdCommand) checkExit(p interface{}, cb func()) {
if c.client.Exited() {
cb()
} else if p != nil && !Killed {
log.Panic(p)
}
}
package plugin
import (
"github.com/mitchellh/packer/packer"
"os/exec"
"testing"
)
type helperCommand byte
func (helperCommand) Help() string {
return "2"
}
func (helperCommand) Run(packer.Environment, []string) int {
return 42
}
func (helperCommand) Synopsis() string {
return "1"
}
func TestCommand_NoExist(t *testing.T) {
c := NewClient(&ClientConfig{Cmd: exec.Command("i-should-not-exist")})
defer c.Kill()
_, err := c.Command()
if err == nil {
t.Fatal("should have error")
}
}
func TestCommand_Good(t *testing.T) {
c := NewClient(&ClientConfig{Cmd: helperProcess("command")})
defer c.Kill()
command, err := c.Command()
if err != nil {
t.Fatalf("should not have error: %s", err)
}
result := command.Synopsis()
if result != "1" {
t.Errorf("synopsis not correct: %s", result)
}
result = command.Help()
if result != "2" {
t.Errorf("help not correct: %s", result)
}
}
......@@ -61,14 +61,6 @@ func TestHelperProcess(*testing.T) {
}
server.RegisterBuilder(new(packer.MockBuilder))
server.Serve()
case "command":
server, err := Server()
if err != nil {
log.Printf("[ERR] %s", err)
os.Exit(1)
}
server.RegisterCommand(new(helperCommand))
server.Serve()
case "hook":
server, err := Server()
if err != nil {
......
......@@ -90,13 +90,6 @@ func (c *Client) Cache() packer.Cache {
}
}
func (c *Client) Command() packer.Command {
return &command{
client: c.client,
mux: c.mux,
}
}
func (c *Client) Communicator() packer.Communicator {
return &communicator{
client: c.client,
......
package rpc
import (
"github.com/mitchellh/packer/packer"
"net/rpc"
)
// A Command is an implementation of the packer.Command interface where the
// command is actually executed over an RPC connection.
type command struct {
client *rpc.Client
mux *muxBroker
}
// A CommandServer wraps a packer.Command and makes it exportable as part
// of a Golang RPC server.
type CommandServer struct {
command packer.Command
mux *muxBroker
}
type CommandRunArgs struct {
Args []string
StreamId uint32
}
type CommandSynopsisArgs byte
func (c *command) Help() (result string) {
err := c.client.Call("Command.Help", new(interface{}), &result)
if err != nil {
panic(err)
}
return
}
func (c *command) Run(env packer.Environment, args []string) (result int) {
nextId := c.mux.NextId()
server := newServerWithMux(c.mux, nextId)
server.RegisterEnvironment(env)
go server.Serve()
rpcArgs := &CommandRunArgs{
Args: args,
StreamId: nextId,
}
err := c.client.Call("Command.Run", rpcArgs, &result)
if err != nil {
panic(err)
}
return
}
func (c *command) Synopsis() (result string) {
err := c.client.Call("Command.Synopsis", CommandSynopsisArgs(0), &result)
if err != nil {
panic(err)
}
return
}
func (c *CommandServer) Help(args *interface{}, reply *string) error {
*reply = c.command.Help()
return nil
}
func (c *CommandServer) Run(args *CommandRunArgs, reply *int) error {
client, err := newClientWithMux(c.mux, args.StreamId)
if err != nil {
return NewBasicError(err)
}
defer client.Close()
*reply = c.command.Run(client.Environment(), args.Args)
return nil
}
func (c *CommandServer) Synopsis(args *CommandSynopsisArgs, reply *string) error {
*reply = c.command.Synopsis()
return nil
}
package rpc
import (
"github.com/mitchellh/packer/packer"
"reflect"
"testing"
)
type TestCommand struct {
runArgs []string
runCalled bool
runEnv packer.Environment
}
func (tc *TestCommand) Help() string {
return "bar"
}
func (tc *TestCommand) Run(env packer.Environment, args []string) int {
tc.runCalled = true
tc.runArgs = args
tc.runEnv = env
return 0
}
func (tc *TestCommand) Synopsis() string {
return "foo"
}
func TestRPCCommand(t *testing.T) {
// Create the command
command := new(TestCommand)
// Start the server
client, server := testClientServer(t)
defer client.Close()
defer server.Close()
server.RegisterCommand(command)
commClient := client.Command()
//Test Help
help := commClient.Help()
if help != "bar" {
t.Fatalf("bad: %s", help)
}
// Test run
runArgs := []string{"foo", "bar"}
testEnv := &testEnvironment{}
exitCode := commClient.Run(testEnv, runArgs)
if !reflect.DeepEqual(command.runArgs, runArgs) {
t.Fatalf("bad: %#v", command.runArgs)
}
if exitCode != 0 {
t.Fatalf("bad: %d", exitCode)
}
if command.runEnv == nil {
t.Fatal("runEnv should not be nil")
}
// Test Synopsis
synopsis := commClient.Synopsis()
if synopsis != "foo" {
t.Fatalf("bad: %#v", synopsis)
}
}
func TestCommand_Implements(t *testing.T) {
var _ packer.Command = new(command)
}
......@@ -20,10 +20,6 @@ type EnvironmentServer struct {
mux *muxBroker
}
type EnvironmentCliArgs struct {
Args []string
}
func (e *Environment) Builder(name string) (b packer.Builder, err error) {
var streamId uint32
err = e.client.Call("Environment.Builder", name, &streamId)
......@@ -53,12 +49,6 @@ func (e *Environment) Cache() packer.Cache {
return client.Cache()
}
func (e *Environment) Cli(args []string) (result int, err error) {
rpcArgs := &EnvironmentCliArgs{args}
err = e.client.Call("Environment.Cli", rpcArgs, &result)
return
}
func (e *Environment) Hook(name string) (h packer.Hook, err error) {
var streamId uint32
err = e.client.Call("Environment.Hook", name, &streamId)
......@@ -138,11 +128,6 @@ func (e *EnvironmentServer) Cache(args *interface{}, reply *uint32) error {
return nil
}
func (e *EnvironmentServer) Cli(args *EnvironmentCliArgs, reply *int) (err error) {
*reply, err = e.env.Cli(args.Args)
return
}
func (e *EnvironmentServer) Hook(name string, reply *uint32) error {
hook, err := e.env.Hook(name)
if err != nil {
......
......@@ -2,7 +2,6 @@ package rpc
import (
"github.com/mitchellh/packer/packer"
"reflect"
"testing"
)
......@@ -95,19 +94,6 @@ func TestEnvironmentRPC(t *testing.T) {
t.Fatal("should be called")
}
// Test Cli
cliArgs := []string{"foo", "bar"}
result, _ := eClient.Cli(cliArgs)
if !e.cliCalled {
t.Fatal("should be called")
}
if !reflect.DeepEqual(e.cliArgs, cliArgs) {
t.Fatalf("bad: %#v", e.cliArgs)
}
if result != 42 {
t.Fatalf("bad: %#v", result)
}
// Test Provisioner
_, _ = eClient.Provisioner("foo")
if !e.provCalled {
......
......@@ -88,13 +88,6 @@ func (s *Server) RegisterCache(c packer.Cache) {
})
}
func (s *Server) RegisterCommand(c packer.Command) {
s.server.RegisterName(DefaultCommandEndpoint, &CommandServer{
command: c,
mux: s.mux,
})
}
func (s *Server) RegisterCommunicator(c packer.Communicator) {
s.server.RegisterName(DefaultCommunicatorEndpoint, &CommunicatorServer{
c: c,
......
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