github.com/kaixiang/packer@v0.5.2-0.20140114230416-1f5786b0d7f1/packer/rpc/provisioner.go (about)

     1  package rpc
     2  
     3  import (
     4  	"github.com/mitchellh/packer/packer"
     5  	"log"
     6  	"net/rpc"
     7  )
     8  
     9  // An implementation of packer.Provisioner where the provisioner is actually
    10  // executed over an RPC connection.
    11  type provisioner struct {
    12  	client *rpc.Client
    13  	mux    *MuxConn
    14  }
    15  
    16  // ProvisionerServer wraps a packer.Provisioner implementation and makes it
    17  // exportable as part of a Golang RPC server.
    18  type ProvisionerServer struct {
    19  	p   packer.Provisioner
    20  	mux *MuxConn
    21  }
    22  
    23  type ProvisionerPrepareArgs struct {
    24  	Configs []interface{}
    25  }
    26  
    27  func (p *provisioner) Prepare(configs ...interface{}) (err error) {
    28  	args := &ProvisionerPrepareArgs{configs}
    29  	if cerr := p.client.Call("Provisioner.Prepare", args, &err); cerr != nil {
    30  		err = cerr
    31  	}
    32  
    33  	return
    34  }
    35  
    36  func (p *provisioner) Provision(ui packer.Ui, comm packer.Communicator) error {
    37  	nextId := p.mux.NextId()
    38  	server := newServerWithMux(p.mux, nextId)
    39  	server.RegisterCommunicator(comm)
    40  	server.RegisterUi(ui)
    41  	go server.Serve()
    42  
    43  	return p.client.Call("Provisioner.Provision", nextId, new(interface{}))
    44  }
    45  
    46  func (p *provisioner) Cancel() {
    47  	err := p.client.Call("Provisioner.Cancel", new(interface{}), new(interface{}))
    48  	if err != nil {
    49  		log.Printf("Provisioner.Cancel err: %s", err)
    50  	}
    51  }
    52  
    53  func (p *ProvisionerServer) Prepare(args *ProvisionerPrepareArgs, reply *error) error {
    54  	*reply = p.p.Prepare(args.Configs...)
    55  	if *reply != nil {
    56  		*reply = NewBasicError(*reply)
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  func (p *ProvisionerServer) Provision(streamId uint32, reply *interface{}) error {
    63  	client, err := newClientWithMux(p.mux, streamId)
    64  	if err != nil {
    65  		return NewBasicError(err)
    66  	}
    67  	defer client.Close()
    68  
    69  	if err := p.p.Provision(client.Ui(), client.Communicator()); err != nil {
    70  		return NewBasicError(err)
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  func (p *ProvisionerServer) Cancel(args *interface{}, reply *interface{}) error {
    77  	p.p.Cancel()
    78  	return nil
    79  }