github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/packer/rpc/build.go (about) 1 package rpc 2 3 import ( 4 "net/rpc" 5 6 "github.com/mitchellh/packer/packer" 7 ) 8 9 // An implementation of packer.Build where the build is actually executed 10 // over an RPC connection. 11 type build struct { 12 client *rpc.Client 13 mux *muxBroker 14 } 15 16 // BuildServer wraps a packer.Build implementation and makes it exportable 17 // as part of a Golang RPC server. 18 type BuildServer struct { 19 build packer.Build 20 mux *muxBroker 21 } 22 23 type BuildPrepareResponse struct { 24 Warnings []string 25 Error *BasicError 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() ([]string, error) { 34 var resp BuildPrepareResponse 35 if cerr := b.client.Call("Build.Prepare", new(interface{}), &resp); 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 *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) { 47 nextId := b.mux.NextId() 48 server := newServerWithMux(b.mux, nextId) 49 server.RegisterCache(cache) 50 server.RegisterUi(ui) 51 go server.Serve() 52 53 var result []uint32 54 if err := b.client.Call("Build.Run", nextId, &result); err != nil { 55 return nil, err 56 } 57 58 artifacts := make([]packer.Artifact, len(result)) 59 for i, streamId := range result { 60 client, err := newClientWithMux(b.mux, streamId) 61 if err != nil { 62 return nil, err 63 } 64 65 artifacts[i] = client.Artifact() 66 } 67 68 return artifacts, nil 69 } 70 71 func (b *build) SetDebug(val bool) { 72 if err := b.client.Call("Build.SetDebug", val, new(interface{})); err != nil { 73 panic(err) 74 } 75 } 76 77 func (b *build) SetForce(val bool) { 78 if err := b.client.Call("Build.SetForce", val, new(interface{})); err != nil { 79 panic(err) 80 } 81 } 82 83 func (b *build) SetOnError(val string) { 84 if err := b.client.Call("Build.SetOnError", val, new(interface{})); err != nil { 85 panic(err) 86 } 87 } 88 89 func (b *build) Cancel() { 90 if err := b.client.Call("Build.Cancel", new(interface{}), new(interface{})); err != nil { 91 panic(err) 92 } 93 } 94 95 func (b *BuildServer) Name(args *interface{}, reply *string) error { 96 *reply = b.build.Name() 97 return nil 98 } 99 100 func (b *BuildServer) Prepare(args *interface{}, resp *BuildPrepareResponse) error { 101 warnings, err := b.build.Prepare() 102 *resp = BuildPrepareResponse{ 103 Warnings: warnings, 104 Error: NewBasicError(err), 105 } 106 return nil 107 } 108 109 func (b *BuildServer) Run(streamId uint32, reply *[]uint32) error { 110 client, err := newClientWithMux(b.mux, streamId) 111 if err != nil { 112 return NewBasicError(err) 113 } 114 defer client.Close() 115 116 artifacts, err := b.build.Run(client.Ui(), client.Cache()) 117 if err != nil { 118 return NewBasicError(err) 119 } 120 121 *reply = make([]uint32, len(artifacts)) 122 for i, artifact := range artifacts { 123 streamId := b.mux.NextId() 124 server := newServerWithMux(b.mux, streamId) 125 server.RegisterArtifact(artifact) 126 go server.Serve() 127 128 (*reply)[i] = streamId 129 } 130 131 return nil 132 } 133 134 func (b *BuildServer) SetDebug(val *bool, reply *interface{}) error { 135 b.build.SetDebug(*val) 136 return nil 137 } 138 139 func (b *BuildServer) SetForce(val *bool, reply *interface{}) error { 140 b.build.SetForce(*val) 141 return nil 142 } 143 144 func (b *BuildServer) SetOnError(val *string, reply *interface{}) error { 145 b.build.SetOnError(*val) 146 return nil 147 } 148 149 func (b *BuildServer) Cancel(args *interface{}, reply *interface{}) error { 150 b.build.Cancel() 151 return nil 152 }