mirror of https://github.com/hashicorp/packer
parent
f082b1b34f
commit
a9b0081828
@ -0,0 +1,38 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io"
|
||||
"net/rpc"
|
||||
)
|
||||
|
||||
// Client is the client end that communicates with a Packer RPC server.
|
||||
// Establishing a connection is up to the user, the Client can just
|
||||
// communicate over any ReadWriteCloser.
|
||||
type Client struct {
|
||||
mux *MuxConn
|
||||
client *rpc.Client
|
||||
}
|
||||
|
||||
func NewClient(rwc io.ReadWriteCloser) (*Client, error) {
|
||||
// Create the MuxConn around the RWC and get the client to server stream.
|
||||
// This is the primary stream that we use to communicate with the
|
||||
// remote RPC server. On the remote side Server.ServeConn also listens
|
||||
// on this stream ID.
|
||||
mux := NewMuxConn(rwc)
|
||||
stream, err := mux.Dial(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{
|
||||
mux: mux,
|
||||
client: rpc.NewClient(stream),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) Artifact() packer.Artifact {
|
||||
return &artifact{
|
||||
client: c.client,
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testClient(t *testing.T, server *Server) *Client {
|
||||
return nil
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io"
|
||||
"log"
|
||||
"net/rpc"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Server represents an RPC server for Packer. This must be paired on
|
||||
// the other side with a Client.
|
||||
type Server struct {
|
||||
endpointId uint64
|
||||
rpcServer *rpc.Server
|
||||
}
|
||||
|
||||
// NewServer returns a new Packer RPC server.
|
||||
func NewServer() *Server {
|
||||
return &Server{
|
||||
endpointId: 0,
|
||||
rpcServer: rpc.NewServer(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterArtifact(a packer.Artifact) {
|
||||
s.registerComponent("Artifact", &ArtifactServer{a}, false)
|
||||
}
|
||||
|
||||
// ServeConn serves a single connection over the RPC server. It is up
|
||||
// to the caller to obtain a proper io.ReadWriteCloser.
|
||||
func (s *Server) ServeConn(conn io.ReadWriteCloser) {
|
||||
mux := NewMuxConn(conn)
|
||||
defer mux.Close()
|
||||
|
||||
// Get stream ID 0, which we always use as the stream for serving
|
||||
// our RPC server on.
|
||||
stream, err := mux.Accept(0)
|
||||
if err != nil {
|
||||
log.Printf("[ERR] Error retrieving stream for serving: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
s.rpcServer.ServeConn(stream)
|
||||
}
|
||||
|
||||
// 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 (s *Server) registerComponent(name string, rcvr interface{}, id bool) string {
|
||||
endpoint := name
|
||||
if id {
|
||||
fmt.Sprintf("%s.%d", endpoint, atomic.AddUint64(&s.endpointId, 1))
|
||||
}
|
||||
|
||||
s.rpcServer.RegisterName(endpoint, rcvr)
|
||||
return endpoint
|
||||
}
|
||||
Loading…
Reference in new issue