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

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