@@ -3,12 +3,15 @@ package system
3
3
import (
4
4
"bytes"
5
5
"crypto/sha256"
6
+ "encoding/binary"
6
7
"fmt"
7
8
"io"
8
9
"context"
10
+ "os"
9
11
"strings"
10
12
"github.com/docker/v2c/api"
11
13
"github.com/docker/docker/api/types"
14
+ "github.com/docker/docker/api/types/volume"
12
15
"github.com/docker/docker/api/types/filters"
13
16
"github.com/docker/docker/api/types/container"
14
17
"github.com/docker/docker/api/types/network"
@@ -124,23 +127,40 @@ func RemoveProducts(is []string, f bool, p bool) ([]types.ImageDelete, error) {
124
127
return result , nil
125
128
}
126
129
127
- func LaunchPackager (ctx context.Context , p api.Packager ) (string , error ) {
130
+ func LaunchPackager (ctx context.Context , p api.Packager , input string ) (string , error ) {
128
131
client , err := docker .NewEnvClient ()
129
132
if err != nil {
130
133
return `` , err
131
134
}
132
135
136
+ // verify absent and create a named volume
137
+ volname := `v2c-transport`
138
+ if _ , err = client .VolumeInspect (gcontext .Background (), volname ); err == nil {
139
+ // TODO: Disable for release, but leave for testing
140
+ //return ``, fmt.Errorf(`The v2c-transport volume already exists.`)
141
+ return `` , nil
142
+ }
143
+ if _ , err = client .VolumeCreate (gcontext .Background (), volume.VolumesCreateBody {
144
+ Name : volname ,
145
+ Driver : `local` ,
146
+ }); err != nil {
147
+ return `` , err
148
+ }
149
+
150
+ fmt .Printf ("Creating container for %v:%v\n " , p .Repository , p .Tag )
133
151
// Create
134
152
createResult , err := client .ContainerCreate (gcontext .Background (),
135
153
& container.Config {
136
154
Image : fmt .Sprintf (`%v:%v` , p .Repository , p .Tag ),
137
155
},
138
156
& container.HostConfig {
139
157
NetworkMode : `none` ,
158
+ Binds : []string {
159
+ fmt .Sprintf (`%s:/input/input.vmdk` , input ),
160
+ fmt .Sprintf (`%s:/v2c` , volname ),
161
+ },
140
162
},
141
- & network.NetworkingConfig {
142
-
143
- },
163
+ & network.NetworkingConfig {},
144
164
fmt .Sprintf ("%x" , sha256 .Sum256 ([]byte (fmt .Sprintf ("%v/%v" , p .Repository , p .Tag )))),
145
165
)
146
166
if err != nil {
@@ -150,14 +170,26 @@ func LaunchPackager(ctx context.Context, p api.Packager) (string, error) {
150
170
// Run
151
171
err = client .ContainerStart (gcontext .Background (),
152
172
createResult .ID ,
153
- types.ContainerStartOptions {
154
-
155
- },
173
+ types.ContainerStartOptions {},
156
174
)
157
175
if err != nil {
158
176
return `` , err
159
177
}
160
178
179
+ // Wait for the container to stop
180
+ code , err := client .ContainerWait (gcontext .Background (), createResult .ID )
181
+ if err != nil {
182
+ panic (err )
183
+ }
184
+ if code != 0 {
185
+ logs , err := client .ContainerLogs (gcontext .Background (), createResult .ID , types.ContainerLogsOptions {})
186
+ if err != nil && logs != nil {
187
+ defer logs .Close ()
188
+ io .Copy (os .Stderr , logs )
189
+ }
190
+ return `` , fmt .Errorf (`The packager failed with code: %v` , code )
191
+ }
192
+
161
193
// return container ID
162
194
return createResult .ID , nil
163
195
}
@@ -169,20 +201,18 @@ func LaunchDetective(ctx context.Context, pc string, c chan *bytes.Buffer, d api
169
201
}
170
202
171
203
// Start a container from the image described by d
172
- // include Volumes From pc
173
204
205
+ fmt .Printf ("Creating container for %v:%v\n " , d .Repository , d .Tag )
174
206
// Create
175
207
createResult , err := client .ContainerCreate (gcontext .Background (),
176
208
& container.Config {
177
209
Image : fmt .Sprintf (`%v:%v` , d .Repository , d .Tag ),
178
210
},
179
211
& container.HostConfig {
180
- VolumesFrom : []string {pc },
212
+ Binds : []string { `v2c-transport:/v2c:ro` },
181
213
NetworkMode : `none` ,
182
214
},
183
- & network.NetworkingConfig {
184
-
185
- },
215
+ & network.NetworkingConfig {},
186
216
fmt .Sprintf ("%x" , sha256 .Sum256 ([]byte (fmt .Sprintf ("%v/%v" , d .Repository , d .Tag )))),
187
217
)
188
218
if err != nil {
@@ -199,33 +229,38 @@ func LaunchDetective(ctx context.Context, pc string, c chan *bytes.Buffer, d api
199
229
// Run
200
230
err = client .ContainerStart (gcontext .Background (),
201
231
createResult .ID ,
202
- types.ContainerStartOptions {
203
-
204
- },
232
+ types.ContainerStartOptions {},
205
233
)
206
234
if err != nil {
207
235
panic (err )
208
236
}
209
237
210
- // Skip the first 8 bytes...
211
- // TODO: do something a bit more purposeful
212
- _ , err = attachment .Reader .Discard (8 )
213
- if err != nil {
214
- panic (err )
215
- }
216
-
217
- // Read from attachment until conn is closed or eof or whatever...
238
+ // Copy the buffer
218
239
stdout := new (bytes.Buffer )
219
- _ , err = io .Copy (stdout , attachment .Reader )
220
- if err != nil && err != io .EOF {
240
+ for {
241
+ if _ , err = attachment .Reader .Discard (4 ); err != nil {
242
+ break
243
+ }
244
+ var chunkSize uint32
245
+ if err = binary .Read (attachment .Reader , binary .BigEndian , & chunkSize ); err != nil {
246
+ break
247
+ }
248
+ if _ , err = io .CopyN (stdout , attachment .Reader , int64 (chunkSize )); err != nil {
249
+ break
250
+ }
251
+ }
252
+ if err != io .EOF {
221
253
panic (err )
222
254
}
223
255
256
+
224
257
// Wait for the container to stop
225
- code , err := client .ContainerWait (ctx , createResult .ID )
258
+ var code int64
259
+ code , err = client .ContainerWait (ctx , createResult .ID )
226
260
if err != nil {
227
261
panic (err )
228
262
}
263
+
229
264
if code != 0 {
230
265
fmt .Printf ("No results for %v:%v code: %v\n " , d .Repository , d .Tag ,code )
231
266
stdout = nil
@@ -248,6 +283,7 @@ func LaunchProvisioner(ctx context.Context, in *bytes.Buffer, c chan *bytes.Buff
248
283
panic (err )
249
284
}
250
285
286
+ fmt .Printf ("Creating container for %v:%v\n " , p .Repository , p .Tag )
251
287
// Start a container from the image described by p
252
288
createResult , err := client .ContainerCreate (gcontext .Background (),
253
289
& container.Config {
@@ -293,20 +329,25 @@ func LaunchProvisioner(ctx context.Context, in *bytes.Buffer, c chan *bytes.Buff
293
329
}
294
330
attachment .CloseWrite ()
295
331
296
- // Skip the first 8 bytes...
297
- // TODO: do something a bit more purposeful
298
- _ , err = attachment .Reader .Discard (8 )
299
- if err != nil {
300
- panic (err )
301
- }
302
-
303
- // read from attachment until conn is closed or eof or whatever...
332
+ // Copy the buffer
304
333
stdout := new (bytes.Buffer )
305
- _ , err = io .Copy (stdout , attachment .Reader )
306
- if err != nil && err != io .EOF {
334
+ for {
335
+ if _ , err = attachment .Reader .Discard (4 ); err != nil {
336
+ break
337
+ }
338
+ var chunkSize uint32
339
+ if err = binary .Read (attachment .Reader , binary .BigEndian , & chunkSize ); err != nil {
340
+ break
341
+ }
342
+ if _ , err = io .CopyN (stdout , attachment .Reader , int64 (chunkSize )); err != nil {
343
+ break
344
+ }
345
+ }
346
+ if err != io .EOF {
307
347
panic (err )
308
348
}
309
349
350
+
310
351
// Wait for the container to stop
311
352
code , err := client .ContainerWait (ctx , createResult .ID )
312
353
if err != nil {
0 commit comments