2013-12-09 17:24:55 -05:00
|
|
|
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()
|
|
|
|
|
2013-12-09 17:44:26 -05:00
|
|
|
// Accept a connection on stream ID 0, which is always used for
|
|
|
|
// normal client to server connections.
|
2013-12-09 17:24:55 -05:00
|
|
|
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
|
|
|
|
}
|