Exemplo n.º 1
0
func NewRpcClientDriver(rawDriverData []byte, driverName string) (*RpcClientDriver, error) {
	mcnName := ""

	p := localbinary.NewLocalBinaryPlugin(driverName)

	go func() {
		if err := p.Serve(); err != nil {
			// If we can't safely load the server, best to just
			// bail.
			log.Fatal(err)
		}
	}()

	addr, err := p.Address()
	if err != nil {
		return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err)
	}

	rpcclient, err := rpc.DialHTTP("tcp", addr)
	if err != nil {
		return nil, err
	}

	c := &RpcClientDriver{
		Client:          NewInternalClient(rpcclient),
		heartbeatDoneCh: make(chan bool),
	}

	go func(heartbeatDoneCh <-chan bool) {
		for {
			select {
			case <-heartbeatDoneCh:
				return
			default:
				if err := c.Client.Call("RpcServerDriver.Heartbeat", struct{}{}, nil); err != nil {
					log.Warnf("Error attempting heartbeat call to plugin server: %s", err)
				}
				time.Sleep(heartbeatInterval)
			}
		}
	}(c.heartbeatDoneCh)

	var version int
	if err := c.Client.Call("RpcServerDriver.GetVersion", struct{}{}, &version); err != nil {
		return nil, err
	}
	log.Debug("Using API Version ", version)

	if err := c.SetConfigRaw(rawDriverData); err != nil {
		return nil, err
	}

	mcnName = c.GetMachineName()
	p.MachineName = mcnName
	c.Client.MachineName = mcnName
	c.plugin = p

	return c, nil
}
func NewRpcClientDriver(rawDriverData []byte, driverName string) (*RpcClientDriver, error) {
	mcnName := ""

	p := localbinary.NewLocalBinaryPlugin(driverName)

	c := &RpcClientDriver{}

	go func() {
		if err := p.Serve(); err != nil {
			// If we can't safely load the server, best to just
			// bail.
			log.Fatal(err)
		}
	}()

	addr, err := p.Address()
	if err != nil {
		return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err)
	}

	rpcclient, err := rpc.DialHTTP("tcp", addr)
	if err != nil {
		return nil, err
	}

	c.Client = NewInternalClient(rpcclient)

	go func() {
		for {
			call := <-c.Client.Calls

			log.Debugf("(%s) Got msg %+v", mcnName, call)

			if call.ServiceMethod == "RpcServerDriver.Close" {
				p.Close()
			}

			c.Client.CallErrs <- c.Client.RpcClient.Call(call.ServiceMethod, call.Args, call.Reply)

			if call.ServiceMethod == "RpcServerDriver.Close" {
				// If we're messaging the server to close,
				// we're not accepting any more RPC calls at
				// all, so return from this function
				// (subsequent "requests" to make a call by
				// sending on the Calls channel will simply
				// block and never go through)
				return
			}
		}
	}()

	var version int
	if err := c.Client.Call("RpcServerDriver.GetVersion", struct{}{}, &version); err != nil {
		return nil, err
	}
	log.Debug("Using API Version ", version)

	if err := c.SetConfigRaw(rawDriverData); err != nil {
		return nil, err
	}

	mcnName = c.GetMachineName()
	p.MachineName = mcnName

	return c, nil
}
Exemplo n.º 3
0
func NewRpcClientDriver(rawDriverData []byte, driverName string) (*RpcClientDriver, error) {
	mcnName := ""

	p, err := localbinary.NewLocalBinaryPlugin(driverName)
	if err != nil {
		return nil, err
	}

	go func() {
		if err := p.Serve(); err != nil {
			// TODO: Is this best approach?
			log.Warn(err)
			return
		}
	}()

	addr, err := p.Address()
	if err != nil {
		return nil, fmt.Errorf("Error attempting to get plugin server address for RPC: %s", err)
	}

	rpcclient, err := rpc.DialHTTP("tcp", addr)
	if err != nil {
		return nil, err
	}

	c := &RpcClientDriver{
		Client:          NewInternalClient(rpcclient),
		heartbeatDoneCh: make(chan bool),
	}

	go func(c *RpcClientDriver) {
		for {
			select {
			case <-c.heartbeatDoneCh:
				return
			default:
				if err := c.Client.Call("RpcServerDriver.Heartbeat", struct{}{}, nil); err != nil {
					log.Warnf("Error attempting heartbeat call to plugin server: %s", err)
					c.Close()
					return
				}
				time.Sleep(heartbeatInterval)
			}
		}
	}(c)

	var serverVersion int
	if err := c.Client.Call("RpcServerDriver.GetVersion", struct{}{}, &serverVersion); err != nil {
		return nil, err
	}

	if serverVersion != version.APIVersion {
		return nil, fmt.Errorf("Driver binary uses an incompatible API version (%d)", serverVersion)
	}
	log.Debug("Using API Version ", serverVersion)

	if err := c.SetConfigRaw(rawDriverData); err != nil {
		return nil, err
	}

	mcnName = c.GetMachineName()
	p.MachineName = mcnName
	c.Client.MachineName = mcnName
	c.plugin = p

	return c, nil
}