2013-05-04 02:55:08 -04:00
|
|
|
package rpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"github.com/mitchellh/packer/packer"
|
|
|
|
"net"
|
|
|
|
"net/rpc"
|
|
|
|
)
|
|
|
|
|
2013-05-05 19:25:32 -04:00
|
|
|
func RegisterCommand(s *rpc.Server, c packer.Command) {
|
|
|
|
s.RegisterName("Command", &ServerCommand{c})
|
|
|
|
}
|
|
|
|
|
2013-05-04 02:55:08 -04:00
|
|
|
// A Server is a Golang RPC server that has helper methods for automatically
|
|
|
|
// setting up the endpoints for Packer interfaces.
|
|
|
|
type Server struct {
|
2013-05-04 16:23:28 -04:00
|
|
|
listener net.Listener
|
2013-05-04 02:55:08 -04:00
|
|
|
server *rpc.Server
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates and returns a new Server.
|
|
|
|
func NewServer() *Server {
|
|
|
|
return &Server{
|
|
|
|
server: rpc.NewServer(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) Address() string {
|
2013-05-04 16:23:28 -04:00
|
|
|
if s.listener == nil {
|
|
|
|
panic("Server not listening.")
|
|
|
|
}
|
|
|
|
|
|
|
|
return s.listener.Addr().String()
|
2013-05-04 02:55:08 -04:00
|
|
|
}
|
|
|
|
|
2013-05-04 16:47:11 -04:00
|
|
|
func (s *Server) RegisterBuild(b packer.Build) {
|
|
|
|
s.server.RegisterName("Build", &BuildServer{b})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) RegisterBuilder(b packer.Builder) {
|
|
|
|
s.server.RegisterName("Builder", &BuilderServer{b})
|
|
|
|
}
|
|
|
|
|
2013-05-05 00:26:30 -04:00
|
|
|
func (s *Server) RegisterCommand(c packer.Command) {
|
|
|
|
s.server.RegisterName("Command", &ServerCommand{c})
|
|
|
|
}
|
|
|
|
|
2013-05-04 18:58:42 -04:00
|
|
|
func (s *Server) RegisterEnvironment(e packer.Environment) {
|
|
|
|
s.server.RegisterName("Environment", &EnvironmentServer{e})
|
|
|
|
}
|
|
|
|
|
2013-05-04 02:55:08 -04:00
|
|
|
func (s *Server) RegisterUi(ui packer.Ui) {
|
|
|
|
s.server.RegisterName("Ui", &UiServer{ui})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) Start() error {
|
2013-05-04 18:33:36 -04:00
|
|
|
return s.start(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) StartSingle() error {
|
|
|
|
return s.start(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) Stop() {
|
|
|
|
if s.listener != nil {
|
|
|
|
s.listener.Close()
|
|
|
|
s.listener = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Server) start(singleConn bool) error {
|
2013-05-04 16:23:28 -04:00
|
|
|
if s.listener != nil {
|
2013-05-04 02:55:08 -04:00
|
|
|
return errors.New("Server already started.")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start the TCP listener and a goroutine responsible for cleaning up the
|
|
|
|
// listener.
|
2013-05-04 16:23:28 -04:00
|
|
|
s.listener = netListenerInRange(portRangeMin, portRangeMax)
|
|
|
|
if s.listener == nil {
|
|
|
|
return errors.New("Could not open a port ot listen on.")
|
|
|
|
}
|
2013-05-04 02:55:08 -04:00
|
|
|
|
|
|
|
// Start accepting connections
|
2013-05-04 16:29:45 -04:00
|
|
|
go func(l net.Listener) {
|
2013-05-04 02:55:08 -04:00
|
|
|
for {
|
2013-05-04 16:29:45 -04:00
|
|
|
conn, err := l.Accept()
|
2013-05-04 02:55:08 -04:00
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
go s.server.ServeConn(conn)
|
2013-05-04 18:33:36 -04:00
|
|
|
|
|
|
|
// If we're only accepting a single connection then
|
|
|
|
// stop.
|
|
|
|
if singleConn {
|
|
|
|
s.Stop()
|
|
|
|
break
|
|
|
|
}
|
2013-05-04 02:55:08 -04:00
|
|
|
}
|
2013-05-04 16:29:45 -04:00
|
|
|
}(s.listener)
|
2013-05-04 02:55:08 -04:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|