github.com/jerryclinesmith/packer@v0.3.7/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  }
    13  
    14  // BuildServer wraps a packer.Build implementation and makes it exportable
    15  // as part of a Golang RPC server.
    16  type BuildServer struct {
    17  	build packer.Build
    18  }
    19  
    20  type BuildRunArgs struct {
    21  	UiRPCAddress string
    22  }
    23  
    24  func Build(client *rpc.Client) *build {
    25  	return &build{client}
    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(v map[string]string) (err error) {
    34  	if cerr := b.client.Call("Build.Prepare", v, &err); cerr != nil {
    35  		return cerr
    36  	}
    37  
    38  	return
    39  }
    40  
    41  func (b *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) {
    42  	// Create and start the server for the UI
    43  	server := rpc.NewServer()
    44  	RegisterCache(server, cache)
    45  	RegisterUi(server, ui)
    46  	args := &BuildRunArgs{serveSingleConn(server)}
    47  
    48  	var result []string
    49  	if err := b.client.Call("Build.Run", args, &result); err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	artifacts := make([]packer.Artifact, len(result))
    54  	for i, addr := range result {
    55  		client, err := rpc.Dial("tcp", addr)
    56  		if err != nil {
    57  			return nil, err
    58  		}
    59  
    60  		artifacts[i] = Artifact(client)
    61  	}
    62  
    63  	return artifacts, nil
    64  }
    65  
    66  func (b *build) SetDebug(val bool) {
    67  	if err := b.client.Call("Build.SetDebug", val, new(interface{})); err != nil {
    68  		panic(err)
    69  	}
    70  }
    71  
    72  func (b *build) SetForce(val bool) {
    73  	if err := b.client.Call("Build.SetForce", val, new(interface{})); err != nil {
    74  		panic(err)
    75  	}
    76  }
    77  
    78  func (b *build) Cancel() {
    79  	if err := b.client.Call("Build.Cancel", new(interface{}), new(interface{})); err != nil {
    80  		panic(err)
    81  	}
    82  }
    83  
    84  func (b *BuildServer) Name(args *interface{}, reply *string) error {
    85  	*reply = b.build.Name()
    86  	return nil
    87  }
    88  
    89  func (b *BuildServer) Prepare(v map[string]string, reply *error) error {
    90  	*reply = b.build.Prepare(v)
    91  	return nil
    92  }
    93  
    94  func (b *BuildServer) Run(args *BuildRunArgs, reply *[]string) error {
    95  	client, err := rpc.Dial("tcp", args.UiRPCAddress)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	artifacts, err := b.build.Run(&Ui{client}, Cache(client))
   101  	if err != nil {
   102  		return NewBasicError(err)
   103  	}
   104  
   105  	*reply = make([]string, len(artifacts))
   106  	for i, artifact := range artifacts {
   107  		server := rpc.NewServer()
   108  		RegisterArtifact(server, artifact)
   109  		(*reply)[i] = serveSingleConn(server)
   110  	}
   111  
   112  	return nil
   113  }
   114  
   115  func (b *BuildServer) SetDebug(val *bool, reply *interface{}) error {
   116  	b.build.SetDebug(*val)
   117  	return nil
   118  }
   119  
   120  func (b *BuildServer) SetForce(val *bool, reply *interface{}) error {
   121  	b.build.SetForce(*val)
   122  	return nil
   123  }
   124  
   125  func (b *BuildServer) Cancel(args *interface{}, reply *interface{}) error {
   126  	b.build.Cancel()
   127  	return nil
   128  }