packer/rpc: auto-incrementable ID for endpoints

This commit is contained in:
Mitchell Hashimoto 2013-12-08 11:50:14 -08:00
parent 73d691d319
commit a66f148ede
9 changed files with 47 additions and 25 deletions

View File

@ -107,7 +107,8 @@ func (b *BuildServer) Run(args *BuildRunArgs, reply *[]string) error {
return err
}
artifacts, err := b.build.Run(&Ui{client}, Cache(client))
ui := &Ui{client: client}
artifacts, err := b.build.Run(ui, Cache(client))
if err != nil {
return NewBasicError(err)
}

View File

@ -146,7 +146,7 @@ func (b *BuilderServer) Run(args *BuilderRunArgs, reply *interface{}) error {
cache := Cache(client)
hook := Hook(client)
ui := &Ui{client}
ui := &Ui{client: client}
artifact, responseErr := b.builder.Run(ui, hook, cache)
responseAddress := ""

View File

@ -114,7 +114,7 @@ func (e *Environment) Ui() packer.Ui {
panic(err)
}
return &Ui{client}
return &Ui{client: client}
}
func (e *EnvironmentServer) Builder(name *string, reply *string) error {

View File

@ -51,7 +51,7 @@ func (h *HookServer) Run(args *HookRunArgs, reply *interface{}) error {
return err
}
if err := h.hook.Run(args.Name, &Ui{client}, Communicator(client), args.Data); err != nil {
if err := h.hook.Run(args.Name, &Ui{client: client}, Communicator(client), args.Data); err != nil {
return NewBasicError(err)
}

View File

@ -82,7 +82,7 @@ func (p *PostProcessorServer) PostProcess(address string, reply *PostProcessorPr
responseAddress := ""
artifact, keep, err := p.p.PostProcess(&Ui{client}, Artifact(client))
artifact, keep, err := p.p.PostProcess(&Ui{client: client}, Artifact(client))
if err == nil && artifact != nil {
server := rpc.NewServer()
RegisterArtifact(server, artifact)

View File

@ -71,7 +71,7 @@ func (p *ProvisionerServer) Provision(args *ProvisionerProvisionArgs, reply *int
}
comm := Communicator(client)
ui := &Ui{client}
ui := &Ui{client: client}
if err := p.p.Provision(ui, comm); err != nil {
return NewBasicError(err)

View File

@ -1,73 +1,93 @@
package rpc
import (
"fmt"
"github.com/mitchellh/packer/packer"
"net/rpc"
"sync/atomic"
)
// This keeps track of the endpoint ID to use when registering artifacts.
var endpointId uint64 = 0
// Registers the appropriate endpoint on an RPC server to serve an
// Artifact.
func RegisterArtifact(s *rpc.Server, a packer.Artifact) {
s.RegisterName("Artifact", &ArtifactServer{a})
registerComponent(s, "Artifact", &ArtifactServer{a}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Build.
func RegisterBuild(s *rpc.Server, b packer.Build) {
s.RegisterName("Build", &BuildServer{b})
registerComponent(s, "Build", &BuildServer{b}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Builder.
func RegisterBuilder(s *rpc.Server, b packer.Builder) {
s.RegisterName("Builder", &BuilderServer{b})
registerComponent(s, "Builder", &BuilderServer{b}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Cache.
func RegisterCache(s *rpc.Server, c packer.Cache) {
s.RegisterName("Cache", &CacheServer{c})
registerComponent(s, "Cache", &CacheServer{c}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Command.
func RegisterCommand(s *rpc.Server, c packer.Command) {
s.RegisterName("Command", &CommandServer{c})
registerComponent(s, "Command", &CommandServer{c}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Communicator.
func RegisterCommunicator(s *rpc.Server, c packer.Communicator) {
s.RegisterName("Communicator", &CommunicatorServer{c})
registerComponent(s, "Communicator", &CommunicatorServer{c}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer Environment
func RegisterEnvironment(s *rpc.Server, e packer.Environment) {
s.RegisterName("Environment", &EnvironmentServer{e})
registerComponent(s, "Environment", &EnvironmentServer{e}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Hook.
func RegisterHook(s *rpc.Server, hook packer.Hook) {
s.RegisterName("Hook", &HookServer{hook})
func RegisterHook(s *rpc.Server, h packer.Hook) {
registerComponent(s, "Hook", &HookServer{h}, false)
}
// Registers the appropriate endpoing on an RPC server to serve a
// PostProcessor.
func RegisterPostProcessor(s *rpc.Server, p packer.PostProcessor) {
s.RegisterName("PostProcessor", &PostProcessorServer{p})
registerComponent(s, "PostProcessor", &PostProcessorServer{p}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a packer.Provisioner
func RegisterProvisioner(s *rpc.Server, p packer.Provisioner) {
s.RegisterName("Provisioner", &ProvisionerServer{p})
registerComponent(s, "Provisioner", &ProvisionerServer{p}, false)
}
// Registers the appropriate endpoint on an RPC server to serve a
// Packer UI
func RegisterUi(s *rpc.Server, ui packer.Ui) {
s.RegisterName("Ui", &UiServer{ui})
registerComponent(s, "Ui", &UiServer{ui}, false)
}
// registerComponent registers a single Packer RPC component onto
// the RPC server. If id is true, then a unique ID number will be appended
// onto the end of the endpoint.
//
// The endpoint name is returned.
func registerComponent(s *rpc.Server, name string, rcvr interface{}, id bool) string {
endpoint := name
if id {
fmt.Sprintf("%s.%d", endpoint, atomic.AddUint64(&endpointId, 1))
}
s.RegisterName(endpoint, rcvr)
return endpoint
}
func serveSingleConn(s *rpc.Server) string {

View File

@ -10,6 +10,7 @@ import (
// over an RPC connection.
type Ui struct {
client *rpc.Client
endpoint string
}
// UiServer wraps a packer.Ui implementation and makes it exportable
@ -25,12 +26,12 @@ type UiMachineArgs struct {
}
func (u *Ui) Ask(query string) (result string, err error) {
err = u.client.Call("Ui.Ask", query, &result)
err = u.client.Call(u.endpoint+".Ask", query, &result)
return
}
func (u *Ui) Error(message string) {
if err := u.client.Call("Ui.Error", message, new(interface{})); err != nil {
if err := u.client.Call(u.endpoint+".Error", message, new(interface{})); err != nil {
log.Printf("Error in Ui RPC call: %s", err)
}
}
@ -41,19 +42,19 @@ func (u *Ui) Machine(t string, args ...string) {
Args: args,
}
if err := u.client.Call("Ui.Machine", rpcArgs, new(interface{})); err != nil {
if err := u.client.Call(u.endpoint+".Machine", rpcArgs, new(interface{})); err != nil {
log.Printf("Error in Ui RPC call: %s", err)
}
}
func (u *Ui) Message(message string) {
if err := u.client.Call("Ui.Message", message, new(interface{})); err != nil {
if err := u.client.Call(u.endpoint+".Message", message, new(interface{})); err != nil {
log.Printf("Error in Ui RPC call: %s", err)
}
}
func (u *Ui) Say(message string) {
if err := u.client.Call("Ui.Say", message, new(interface{})); err != nil {
if err := u.client.Call(u.endpoint+".Say", message, new(interface{})); err != nil {
log.Printf("Error in Ui RPC call: %s", err)
}
}

View File

@ -62,7 +62,7 @@ func TestUiRPC(t *testing.T) {
panic(err)
}
uiClient := &Ui{client}
uiClient := &Ui{client: client, endpoint: "Ui"}
// Basic error and say tests
result, err := uiClient.Ask("query")