github.com/kaixiang/packer@v0.5.2-0.20140114230416-1f5786b0d7f1/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 *MuxConn 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 *MuxConn 21 } 22 23 type BuilderPrepareArgs struct { 24 Configs []interface{} 25 } 26 27 type BuilderPrepareResponse struct { 28 Warnings []string 29 Error error 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 39 return resp.Warnings, resp.Error 40 } 41 42 func (b *builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { 43 nextId := b.mux.NextId() 44 server := newServerWithMux(b.mux, nextId) 45 server.RegisterCache(cache) 46 server.RegisterHook(hook) 47 server.RegisterUi(ui) 48 go server.Serve() 49 50 var responseId uint32 51 if err := b.client.Call("Builder.Run", nextId, &responseId); err != nil { 52 return nil, err 53 } 54 55 if responseId == 0 { 56 return nil, nil 57 } 58 59 client, err := newClientWithMux(b.mux, responseId) 60 if err != nil { 61 return nil, err 62 } 63 64 return client.Artifact(), nil 65 } 66 67 func (b *builder) Cancel() { 68 if err := b.client.Call("Builder.Cancel", new(interface{}), new(interface{})); err != nil { 69 log.Printf("Error cancelling builder: %s", err) 70 } 71 } 72 73 func (b *BuilderServer) Prepare(args *BuilderPrepareArgs, reply *BuilderPrepareResponse) error { 74 warnings, err := b.builder.Prepare(args.Configs...) 75 if err != nil { 76 err = NewBasicError(err) 77 } 78 79 *reply = BuilderPrepareResponse{ 80 Warnings: warnings, 81 Error: 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 }