github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/packer/rpc/post_processor.go (about)

     1  package rpc
     2  
     3  import (
     4  	"github.com/mitchellh/packer/packer"
     5  	"net/rpc"
     6  )
     7  
     8  // An implementation of packer.PostProcessor where the PostProcessor is actually
     9  // executed over an RPC connection.
    10  type postProcessor struct {
    11  	client *rpc.Client
    12  	mux    *muxBroker
    13  }
    14  
    15  // PostProcessorServer wraps a packer.PostProcessor implementation and makes it
    16  // exportable as part of a Golang RPC server.
    17  type PostProcessorServer struct {
    18  	client *rpc.Client
    19  	mux    *muxBroker
    20  	p      packer.PostProcessor
    21  }
    22  
    23  type PostProcessorConfigureArgs struct {
    24  	Configs []interface{}
    25  }
    26  
    27  type PostProcessorProcessResponse struct {
    28  	Err      *BasicError
    29  	Keep     bool
    30  	StreamId uint32
    31  }
    32  
    33  func (p *postProcessor) Configure(raw ...interface{}) (err error) {
    34  	args := &PostProcessorConfigureArgs{Configs: raw}
    35  	if cerr := p.client.Call("PostProcessor.Configure", args, new(interface{})); cerr != nil {
    36  		err = cerr
    37  	}
    38  
    39  	return
    40  }
    41  
    42  func (p *postProcessor) PostProcess(ui packer.Ui, a packer.Artifact) (packer.Artifact, bool, error) {
    43  	nextId := p.mux.NextId()
    44  	server := newServerWithMux(p.mux, nextId)
    45  	server.RegisterArtifact(a)
    46  	server.RegisterUi(ui)
    47  	go server.Serve()
    48  
    49  	var response PostProcessorProcessResponse
    50  	if err := p.client.Call("PostProcessor.PostProcess", nextId, &response); err != nil {
    51  		return nil, false, err
    52  	}
    53  
    54  	if response.Err != nil {
    55  		return nil, false, response.Err
    56  	}
    57  
    58  	if response.StreamId == 0 {
    59  		return nil, false, nil
    60  	}
    61  
    62  	client, err := newClientWithMux(p.mux, response.StreamId)
    63  	if err != nil {
    64  		return nil, false, err
    65  	}
    66  
    67  	return client.Artifact(), response.Keep, nil
    68  }
    69  
    70  func (p *PostProcessorServer) Configure(args *PostProcessorConfigureArgs, reply *interface{}) error {
    71  	err := p.p.Configure(args.Configs...)
    72  	return err
    73  }
    74  
    75  func (p *PostProcessorServer) PostProcess(streamId uint32, reply *PostProcessorProcessResponse) error {
    76  	client, err := newClientWithMux(p.mux, streamId)
    77  	if err != nil {
    78  		return NewBasicError(err)
    79  	}
    80  	defer client.Close()
    81  
    82  	streamId = 0
    83  	artifactResult, keep, err := p.p.PostProcess(client.Ui(), client.Artifact())
    84  	if err == nil && artifactResult != nil {
    85  		streamId = p.mux.NextId()
    86  		server := newServerWithMux(p.mux, streamId)
    87  		server.RegisterArtifact(artifactResult)
    88  		go server.Serve()
    89  	}
    90  
    91  	*reply = PostProcessorProcessResponse{
    92  		Err:      NewBasicError(err),
    93  		Keep:     keep,
    94  		StreamId: streamId,
    95  	}
    96  
    97  	return nil
    98  }