github.com/askholme/packer@v0.7.2-0.20140924152349-70d9566a6852/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 *muxBroker 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 *muxBroker 20 } 21 22 type BuildPrepareResponse struct { 23 Warnings []string 24 Error *BasicError 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 var err error = nil 38 if resp.Error != nil { 39 err = resp.Error 40 } 41 42 return resp.Warnings, err 43 } 44 45 func (b *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) { 46 nextId := b.mux.NextId() 47 server := newServerWithMux(b.mux, nextId) 48 server.RegisterCache(cache) 49 server.RegisterUi(ui) 50 go server.Serve() 51 52 var result []uint32 53 if err := b.client.Call("Build.Run", nextId, &result); err != nil { 54 return nil, err 55 } 56 57 artifacts := make([]packer.Artifact, len(result)) 58 for i, streamId := range result { 59 client, err := newClientWithMux(b.mux, streamId) 60 if err != nil { 61 return nil, err 62 } 63 64 artifacts[i] = client.Artifact() 65 } 66 67 return artifacts, nil 68 } 69 70 func (b *build) SetDebug(val bool) { 71 if err := b.client.Call("Build.SetDebug", val, new(interface{})); err != nil { 72 panic(err) 73 } 74 } 75 76 func (b *build) SetForce(val bool) { 77 if err := b.client.Call("Build.SetForce", val, new(interface{})); err != nil { 78 panic(err) 79 } 80 } 81 82 func (b *build) Cancel() { 83 if err := b.client.Call("Build.Cancel", new(interface{}), new(interface{})); err != nil { 84 panic(err) 85 } 86 } 87 88 func (b *BuildServer) Name(args *interface{}, reply *string) error { 89 *reply = b.build.Name() 90 return nil 91 } 92 93 func (b *BuildServer) Prepare(args *interface{}, resp *BuildPrepareResponse) error { 94 warnings, err := b.build.Prepare() 95 *resp = BuildPrepareResponse{ 96 Warnings: warnings, 97 Error: NewBasicError(err), 98 } 99 return nil 100 } 101 102 func (b *BuildServer) Run(streamId uint32, reply *[]uint32) error { 103 client, err := newClientWithMux(b.mux, streamId) 104 if err != nil { 105 return NewBasicError(err) 106 } 107 defer client.Close() 108 109 artifacts, err := b.build.Run(client.Ui(), client.Cache()) 110 if err != nil { 111 return NewBasicError(err) 112 } 113 114 *reply = make([]uint32, len(artifacts)) 115 for i, artifact := range artifacts { 116 streamId := b.mux.NextId() 117 server := newServerWithMux(b.mux, streamId) 118 server.RegisterArtifact(artifact) 119 go server.Serve() 120 121 (*reply)[i] = streamId 122 } 123 124 return nil 125 } 126 127 func (b *BuildServer) SetDebug(val *bool, reply *interface{}) error { 128 b.build.SetDebug(*val) 129 return nil 130 } 131 132 func (b *BuildServer) SetForce(val *bool, reply *interface{}) error { 133 b.build.SetForce(*val) 134 return nil 135 } 136 137 func (b *BuildServer) Cancel(args *interface{}, reply *interface{}) error { 138 b.build.Cancel() 139 return nil 140 }