package rpc import ( "github.com/mitchellh/packer/packer" "github.com/ugorji/go/codec" "io" "log" "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 closeMux bool } func NewClient(rwc io.ReadWriteCloser) (*Client, error) { result, err := newClientWithMux(NewMuxConn(rwc), 0) if err != nil { return nil, err } result.closeMux = true return result, err } func newClientWithMux(mux *MuxConn, streamId uint32) (*Client, error) { clientConn, err := mux.Dial(streamId) if err != nil { return nil, err } var h codec.MsgpackHandle clientCodec := codec.GoRpc.ClientCodec(clientConn, &h) return &Client{ mux: mux, client: rpc.NewClientWithCodec(clientCodec), closeMux: false, }, nil } func (c *Client) Close() error { if err := c.client.Close(); err != nil { return err } if c.closeMux { log.Printf("[WARN] Client is closing mux") return c.mux.Close() } return nil } func (c *Client) Artifact() packer.Artifact { return &artifact{ client: c.client, endpoint: DefaultArtifactEndpoint, } } func (c *Client) Build() packer.Build { return &build{ client: c.client, mux: c.mux, } } func (c *Client) Builder() packer.Builder { return &builder{ client: c.client, mux: c.mux, } } func (c *Client) Cache() packer.Cache { return &cache{ client: c.client, } } 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, mux: c.mux, } } func (c *Client) Environment() packer.Environment { return &Environment{ client: c.client, mux: c.mux, } } func (c *Client) Hook() packer.Hook { return &hook{ client: c.client, mux: c.mux, } } func (c *Client) PostProcessor() packer.PostProcessor { return &postProcessor{ client: c.client, mux: c.mux, } } func (c *Client) Provisioner() packer.Provisioner { return &provisioner{ client: c.client, mux: c.mux, } } func (c *Client) Ui() packer.Ui { return &Ui{ client: c.client, endpoint: DefaultUiEndpoint, } }