@@ -80,7 +80,7 @@ func (e *envs) String() string {
80
80
func (e * envs ) Set (value string ) error {
81
81
kv := strings .SplitN (value , "=" , 2 )
82
82
if len (kv ) != 2 {
83
- return fmt .Errorf ("invalid env string" )
83
+ return fmt .Errorf ("invalid env string %s" , value )
84
84
}
85
85
emap := * e
86
86
emap [kv [0 ]] = kv [1 ]
@@ -148,21 +148,17 @@ type Resources struct {
148
148
Accelerators []Accelerator `json:"accelerators,omitempty"`
149
149
}
150
150
151
- // GCEImage contains some information about CGE Image.
151
+ // GCEImage contains some information about GCE Image.
152
152
type GCEImage struct {
153
153
Image string `json:"image,omitempty"`
154
- ImageDesc string `json:"image_description,omitempty"`
155
- Project string `json:"project"`
156
- Metadata string `json:"metadata"`
157
154
ImageRegex string `json:"image_regex,omitempty"`
158
- // Defaults to using only the latest image. Acceptable values are [0, # of images that match the regex).
159
- // If the number of existing previous images is lesser than what is desired, the test will use that is available.
160
- PreviousImages int `json:"previous_images,omitempty"`
161
- // ImageFamily is the image family to use. The latest image from the image family will be used.
162
- ImageFamily string `json:"image_family,omitempty"`
163
-
164
- Machine string `json:"machine,omitempty"`
165
- Resources Resources `json:"resources,omitempty"`
155
+ // ImageFamily is the image family to use. The latest image from the image family will be used, e.g cos-81-lts.
156
+ ImageFamily string `json:"image_family,omitempty"`
157
+ ImageDesc string `json:"image_description,omitempty"`
158
+ Project string `json:"project"`
159
+ Metadata string `json:"metadata"`
160
+ Machine string `json:"machine,omitempty"`
161
+ Resources Resources `json:"resources,omitempty"`
166
162
// This test is for benchmark (no limit verification, more result log, node name has format 'machine-image-uuid') if 'Tests' is non-empty.
167
163
Tests []string `json:"tests,omitempty"`
168
164
}
@@ -171,6 +167,7 @@ type internalImageConfig struct {
171
167
images map [string ]internalGCEImage
172
168
}
173
169
170
+ // internalGCEImage is an internal GCE image representation for E2E node.
174
171
type internalGCEImage struct {
175
172
image string
176
173
// imageDesc is the description of the image. If empty, the value in the
@@ -218,62 +215,54 @@ func main() {
218
215
gceImages := & internalImageConfig {
219
216
images : make (map [string ]internalGCEImage ),
220
217
}
218
+ // Parse images from given config file and convert them to internalGCEImage.
221
219
if * imageConfigFile != "" {
222
220
configPath := * imageConfigFile
223
221
if * imageConfigDir != "" {
224
222
configPath = filepath .Join (* imageConfigDir , * imageConfigFile )
225
223
}
226
224
227
- // parse images
228
225
imageConfigData , err := ioutil .ReadFile (configPath )
229
226
if err != nil {
230
227
klog .Fatalf ("Could not read image config file provided: %v" , err )
231
228
}
229
+ // Unmarshal the given image config file. All images for this test run will be organized into a map.
230
+ // shortName->GCEImage, e.g cos-stable->cos-stable-81-12871-103-0.
232
231
externalImageConfig := ImageConfig {Images : make (map [string ]GCEImage )}
233
232
err = yaml .Unmarshal (imageConfigData , & externalImageConfig )
234
233
if err != nil {
235
234
klog .Fatalf ("Could not parse image config file: %v" , err )
236
235
}
236
+
237
237
for shortName , imageConfig := range externalImageConfig .Images {
238
- var images []string
239
- isRegex , name := false , shortName
238
+ var image string
240
239
if (imageConfig .ImageRegex != "" || imageConfig .ImageFamily != "" ) && imageConfig .Image == "" {
241
- isRegex = true
242
- images , err = getGCEImages (imageConfig .ImageRegex , imageConfig .ImageFamily , imageConfig .Project , imageConfig .PreviousImages )
240
+ image , err = getGCEImage (imageConfig .ImageRegex , imageConfig .ImageFamily , imageConfig .Project )
243
241
if err != nil {
244
- klog .Fatalf ("Could not retrieve list of images based on image prefix %q and family %q: %v" ,
245
- imageConfig .ImageRegex , imageConfig .ImageFamily , err )
246
- }
247
- if len (images ) == 0 { // if we have no images we can't run anything
248
- klog .Fatalf ("No matching images retrieved on image prefix %q and family %q: %v" ,
242
+ klog .Fatalf ("Could not retrieve a image based on image regex %q and family %q: %v" ,
249
243
imageConfig .ImageRegex , imageConfig .ImageFamily , err )
250
244
}
251
245
} else {
252
- images = [] string { imageConfig .Image }
246
+ image = imageConfig .Image
253
247
}
254
- for _ , image := range images {
255
- metadata := imageConfig .Metadata
256
- if len (strings .TrimSpace (* instanceMetadata )) > 0 {
257
- metadata += "," + * instanceMetadata
258
- }
259
- gceImage := internalGCEImage {
260
- image : image ,
261
- imageDesc : imageConfig .ImageDesc ,
262
- project : imageConfig .Project ,
263
- metadata : getImageMetadata (metadata ),
264
- machine : imageConfig .Machine ,
265
- tests : imageConfig .Tests ,
266
- resources : imageConfig .Resources ,
267
- }
268
- if gceImage .imageDesc == "" {
269
- gceImage .imageDesc = gceImage .image
270
- }
271
- if isRegex && len (images ) > 1 {
272
- // Use image name when shortName is not unique.
273
- name = image
274
- }
275
- gceImages .images [name ] = gceImage
248
+ // Convert the given image into an internalGCEImage.
249
+ metadata := imageConfig .Metadata
250
+ if len (strings .TrimSpace (* instanceMetadata )) > 0 {
251
+ metadata += "," + * instanceMetadata
276
252
}
253
+ gceImage := internalGCEImage {
254
+ image : image ,
255
+ imageDesc : imageConfig .ImageDesc ,
256
+ project : imageConfig .Project ,
257
+ metadata : getImageMetadata (metadata ),
258
+ machine : imageConfig .Machine ,
259
+ tests : imageConfig .Tests ,
260
+ resources : imageConfig .Resources ,
261
+ }
262
+ if gceImage .imageDesc == "" {
263
+ gceImage .imageDesc = gceImage .image
264
+ }
265
+ gceImages .images [shortName ] = gceImage
277
266
}
278
267
}
279
268
@@ -284,21 +273,22 @@ func main() {
284
273
klog .Fatal ("Must specify --image-project if you specify --images" )
285
274
}
286
275
cliImages := strings .Split (* images , "," )
287
- for _ , img := range cliImages {
276
+ for _ , image := range cliImages {
288
277
gceImage := internalGCEImage {
289
- image : img ,
278
+ image : image ,
290
279
project : * imageProject ,
291
280
metadata : getImageMetadata (* instanceMetadata ),
292
281
}
293
- gceImages .images [img ] = gceImage
282
+ gceImages .images [image ] = gceImage
294
283
}
295
284
}
296
285
297
286
if len (gceImages .images ) != 0 && * zone == "" {
298
287
klog .Fatal ("Must specify --zone flag" )
299
288
}
300
- for shortName , image := range gceImages .images {
301
- if image .project == "" {
289
+ // Make sure GCP project is set. Without a project, images can't be retrieved..
290
+ for shortName , imageConfig := range gceImages .images {
291
+ if imageConfig .project == "" {
302
292
klog .Fatalf ("Invalid config for %v; must specify a project" , shortName )
303
293
}
304
294
}
@@ -328,7 +318,7 @@ func main() {
328
318
running := 0
329
319
for shortName := range gceImages .images {
330
320
imageConfig := gceImages .images [shortName ]
331
- fmt .Printf ("Initializing e2e tests using image %s.\n " , shortName )
321
+ fmt .Printf ("Initializing e2e tests using image %s/%s/%s .\n " , shortName , imageConfig . project , imageConfig . image )
332
322
running ++
333
323
go func (image * internalGCEImage , junitFilePrefix string ) {
334
324
results <- testImage (image , junitFilePrefix )
@@ -470,18 +460,14 @@ type imageObj struct {
470
460
name string
471
461
}
472
462
473
- func (io imageObj ) string () string {
474
- return fmt .Sprintf ("%q created %q" , io .name , io .creationTime .String ())
475
- }
476
-
477
463
type byCreationTime []imageObj
478
464
479
465
func (a byCreationTime ) Len () int { return len (a ) }
480
466
func (a byCreationTime ) Less (i , j int ) bool { return a [i ].creationTime .After (a [j ].creationTime ) }
481
467
func (a byCreationTime ) Swap (i , j int ) { a [i ], a [j ] = a [j ], a [i ] }
482
468
483
- // Returns a list of image names based on regex and number of previous images requested .
484
- func getGCEImages (imageRegex , imageFamily string , project string , previousImages int ) ([] string , error ) {
469
+ // Returns an image name based on regex and given GCE project .
470
+ func getGCEImage (imageRegex , imageFamily string , project string ) (string , error ) {
485
471
imageObjs := []imageObj {}
486
472
imageRe := regexp .MustCompile (imageRegex )
487
473
if err := computeService .Images .List (project ).Pages (context .Background (),
@@ -501,24 +487,21 @@ func getGCEImages(imageRegex, imageFamily string, project string, previousImages
501
487
creationTime : creationTime ,
502
488
name : instance .Name ,
503
489
}
504
- klog .V (4 ).Infof ("Found image %q based on regex %q and family %q in project %q" , io .string (), imageRegex , imageFamily , project )
505
490
imageObjs = append (imageObjs , io )
506
491
}
507
492
return nil
508
493
},
509
494
); err != nil {
510
- return nil , fmt .Errorf ("failed to list images in project %q: %v" , project , err )
495
+ return "" , fmt .Errorf ("failed to list images in project %q: %v" , project , err )
511
496
}
497
+
498
+ // Pick the latest image after sorting.
512
499
sort .Sort (byCreationTime (imageObjs ))
513
- images := []string {}
514
- for _ , imageObj := range imageObjs {
515
- images = append (images , imageObj .name )
516
- previousImages --
517
- if previousImages < 0 {
518
- break
519
- }
500
+ if len (imageObjs ) > 0 {
501
+ klog .V (4 ).Infof ("found images %+v based on regex %q and family %q in project %q" , imageObjs , imageRegex , imageFamily , project )
502
+ return imageObjs [0 ].name , nil
520
503
}
521
- return images , nil
504
+ return "" , fmt . Errorf ( "found zero images based on regex %q and family %q in project %q" , imageRegex , imageFamily , project )
522
505
}
523
506
524
507
// Provision a gce instance using image and run the tests in archive against the instance.
0 commit comments