github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/packer/rpc/builder.go (about) 1 package rpc 2 3 import ( 4 "github.com/mitchellh/packer/packer" 5 "log" 6 "net/rpc" 7 ) 8 9 // An implementation of packer.Builder where the builder is actually executed 10 // over an RPC connection. 11 type builder struct { 12 client *rpc.Client 13 mux *muxBroker 14 } 15 16 // BuilderServer wraps a packer.Builder implementation and makes it exportable 17 // as part of a Golang RPC server. 18 type BuilderServer struct { 19 builder packer.Builder 20 mux *muxBroker 21 } 22 23 type BuilderPrepareArgs struct { 24 Configs []interface{} 25 } 26 27 type BuilderPrepareResponse struct { 28 Warnings []string 29 Error *BasicError 30 } 31 32 func (b *builder) Prepare(config ...interface{}) ([]string, error) { 33 var resp BuilderPrepareResponse 34 cerr := b.client.Call("Builder.Prepare", &BuilderPrepareArgs{config}, &resp) 35 if 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 *builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 47 nextId := b.mux.NextId() 48 server := newServerWithMux(b.mux, nextId) 49 server.RegisterCache(cache) 50 server.RegisterHook(hook) 51 server.RegisterUi(ui) 52 go server.Serve() 53 54 var responseId uint32 55 if err := b.client.Call("Builder.Run", nextId, &responseId); err != nil { 56 return nil, err 57 } 58 59 if responseId == 0 { 60 return nil, nil 61 } 62 63 client, err := newClientWithMux(b.mux, responseId) 64 if err != nil { 65 return nil, err 66 } 67 68 return client.Artifact(), nil 69 } 70 71 func (b *builder) Cancel() { 72 if err := b.client.Call("Builder.Cancel", new(interface{}), new(interface{})); err != nil { 73 log.Printf("Error cancelling builder: %s", err) 74 } 75 } 76 77 func (b *BuilderServer) Prepare(args *BuilderPrepareArgs, reply *BuilderPrepareResponse) error { 78 warnings, err := b.builder.Prepare(args.Configs...) 79 *reply = BuilderPrepareResponse{ 80 Warnings: warnings, 81 Error: NewBasicError(err), 82 } 83 return nil 84 } 85 86 func (b *BuilderServer) Run(streamId uint32, reply *uint32) error { 87 client, err := newClientWithMux(b.mux, streamId) 88 if err != nil { 89 return NewBasicError(err) 90 } 91 defer client.Close() 92 93 artifact, err := b.builder.Run(client.Ui(), client.Hook(), client.Cache()) 94 if err != nil { 95 return NewBasicError(err) 96 } 97 98 *reply = 0 99 if artifact != nil { 100 streamId = b.mux.NextId() 101 server := newServerWithMux(b.mux, streamId) 102 server.RegisterArtifact(artifact) 103 go server.Serve() 104 *reply = streamId 105 } 106 107 return nil 108 } 109 110 func (b *BuilderServer) Cancel(args *interface{}, reply *interface{}) error { 111 b.builder.Cancel() 112 return nil 113 }