github.com/jbronn/packer@v0.1.6-0.20140120165540-8a1364dbd817/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 *MuxConn 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 *MuxConn 20 } 21 22 type BuildPrepareResponse struct { 23 Warnings []string 24 Error error 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 38 return resp.Warnings, resp.Error 39 } 40 41 func (b *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) { 42 nextId := b.mux.NextId() 43 server := newServerWithMux(b.mux, nextId) 44 server.RegisterCache(cache) 45 server.RegisterUi(ui) 46 go server.Serve() 47 48 var result []uint32 49 if err := b.client.Call("Build.Run", nextId, &result); err != nil { 50 return nil, err 51 } 52 53 artifacts := make([]packer.Artifact, len(result)) 54 for i, streamId := range result { 55 client, err := newClientWithMux(b.mux, streamId) 56 if err != nil { 57 return nil, err 58 } 59 60 artifacts[i] = client.Artifact() 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(args *interface{}, resp *BuildPrepareResponse) error { 90 warnings, err := b.build.Prepare() 91 *resp = BuildPrepareResponse{ 92 Warnings: warnings, 93 Error: err, 94 } 95 return nil 96 } 97 98 func (b *BuildServer) Run(streamId uint32, reply *[]uint32) error { 99 client, err := newClientWithMux(b.mux, streamId) 100 if err != nil { 101 return NewBasicError(err) 102 } 103 defer client.Close() 104 105 artifacts, err := b.build.Run(client.Ui(), client.Cache()) 106 if err != nil { 107 return NewBasicError(err) 108 } 109 110 *reply = make([]uint32, len(artifacts)) 111 for i, artifact := range artifacts { 112 streamId := b.mux.NextId() 113 server := newServerWithMux(b.mux, streamId) 114 server.RegisterArtifact(artifact) 115 go server.Serve() 116 117 (*reply)[i] = streamId 118 } 119 120 return nil 121 } 122 123 func (b *BuildServer) SetDebug(val *bool, reply *interface{}) error { 124 b.build.SetDebug(*val) 125 return nil 126 } 127 128 func (b *BuildServer) SetForce(val *bool, reply *interface{}) error { 129 b.build.SetForce(*val) 130 return nil 131 } 132 133 func (b *BuildServer) Cancel(args *interface{}, reply *interface{}) error { 134 b.build.Cancel() 135 return nil 136 }