github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/packer/rpc/build.go (about)

     1  package rpc
     2  
     3  import (
     4  	"github.com/mitchellh/packer/packer"
     5  	"net/rpc"
     6  )
     7  
     8  // An implementation of packer.Build where the build is actually executed
     9  // over an RPC connection.
    10  type build struct {
    11  	client *rpc.Client
    12  	mux    *muxBroker
    13  }
    14  
    15  // BuildServer wraps a packer.Build implementation and makes it exportable
    16  // as part of a Golang RPC server.
    17  type BuildServer struct {
    18  	build packer.Build
    19  	mux   *muxBroker
    20  }
    21  
    22  type BuildPrepareResponse struct {
    23  	Warnings []string
    24  	Error    *BasicError
    25  }
    26  
    27  func (b *build) Name() (result string) {
    28  	b.client.Call("Build.Name", new(interface{}), &result)
    29  	return
    30  }
    31  
    32  func (b *build) Prepare() ([]string, error) {
    33  	var resp BuildPrepareResponse
    34  	if cerr := b.client.Call("Build.Prepare", new(interface{}), &resp); cerr != nil {
    35  		return nil, cerr
    36  	}
    37  	var err error = nil
    38  	if resp.Error != nil {
    39  		err = resp.Error
    40  	}
    41  
    42  	return resp.Warnings, err
    43  }
    44  
    45  func (b *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) {
    46  	nextId := b.mux.NextId()
    47  	server := newServerWithMux(b.mux, nextId)
    48  	server.RegisterCache(cache)
    49  	server.RegisterUi(ui)
    50  	go server.Serve()
    51  
    52  	var result []uint32
    53  	if err := b.client.Call("Build.Run", nextId, &result); err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	artifacts := make([]packer.Artifact, len(result))
    58  	for i, streamId := range result {
    59  		client, err := newClientWithMux(b.mux, streamId)
    60  		if err != nil {
    61  			return nil, err
    62  		}
    63  
    64  		artifacts[i] = client.Artifact()
    65  	}
    66  
    67  	return artifacts, nil
    68  }
    69  
    70  func (b *build) SetDebug(val bool) {
    71  	if err := b.client.Call("Build.SetDebug", val, new(interface{})); err != nil {
    72  		panic(err)
    73  	}
    74  }
    75  
    76  func (b *build) SetForce(val bool) {
    77  	if err := b.client.Call("Build.SetForce", val, new(interface{})); err != nil {
    78  		panic(err)
    79  	}
    80  }
    81  
    82  func (b *build) Cancel() {
    83  	if err := b.client.Call("Build.Cancel", new(interface{}), new(interface{})); err != nil {
    84  		panic(err)
    85  	}
    86  }
    87  
    88  func (b *BuildServer) Name(args *interface{}, reply *string) error {
    89  	*reply = b.build.Name()
    90  	return nil
    91  }
    92  
    93  func (b *BuildServer) Prepare(args *interface{}, resp *BuildPrepareResponse) error {
    94  	warnings, err := b.build.Prepare()
    95  	*resp = BuildPrepareResponse{
    96  		Warnings: warnings,
    97  		Error:    NewBasicError(err),
    98  	}
    99  	return nil
   100  }
   101  
   102  func (b *BuildServer) Run(streamId uint32, reply *[]uint32) error {
   103  	client, err := newClientWithMux(b.mux, streamId)
   104  	if err != nil {
   105  		return NewBasicError(err)
   106  	}
   107  	defer client.Close()
   108  
   109  	artifacts, err := b.build.Run(client.Ui(), client.Cache())
   110  	if err != nil {
   111  		return NewBasicError(err)
   112  	}
   113  
   114  	*reply = make([]uint32, len(artifacts))
   115  	for i, artifact := range artifacts {
   116  		streamId := b.mux.NextId()
   117  		server := newServerWithMux(b.mux, streamId)
   118  		server.RegisterArtifact(artifact)
   119  		go server.Serve()
   120  
   121  		(*reply)[i] = streamId
   122  	}
   123  
   124  	return nil
   125  }
   126  
   127  func (b *BuildServer) SetDebug(val *bool, reply *interface{}) error {
   128  	b.build.SetDebug(*val)
   129  	return nil
   130  }
   131  
   132  func (b *BuildServer) SetForce(val *bool, reply *interface{}) error {
   133  	b.build.SetForce(*val)
   134  	return nil
   135  }
   136  
   137  func (b *BuildServer) Cancel(args *interface{}, reply *interface{}) error {
   138  	b.build.Cancel()
   139  	return nil
   140  }