in step_create_images.go [113:174]
func (ci *CreateImages) run(ctx context.Context, s *Step) DError {
var wg sync.WaitGroup
w := s.w
e := make(chan DError)
createImage := func(ci ImageInterface, overwrite bool) {
defer wg.Done()
// Get source disk link if SourceDisk is a daisy reference to a disk.
if d, ok := w.disks.get(ci.getSourceDisk()); ok {
ci.setSourceDisk(d.link)
}
// Delete existing if OverWrite is true.
if overwrite {
// Just try to delete it, a 404 here indicates the image doesn't exist.
if err := ci.delete(w.ComputeClient); err != nil {
if apiErr, ok := err.(*googleapi.Error); !ok || apiErr.Code != 404 {
e <- Errf("error deleting existing image: %v", err)
return
}
}
}
w.LogStepInfo(s.name, "CreateImages", "Creating image %q.", ci.getName())
if err := ci.create(w.ComputeClient); err != nil {
e <- newErr("failed to create images", err)
return
}
ci.markCreatedInWorkflow()
}
if imageUsesAlphaFeatures(ci.ImagesAlpha) {
for _, i := range ci.ImagesAlpha {
wg.Add(1)
go createImage(i, i.OverWrite)
}
} else if imageUsesBetaFeatures(ci.ImagesBeta) {
for _, i := range ci.ImagesBeta {
wg.Add(1)
go createImage(i, i.OverWrite)
}
} else {
for _, i := range ci.Images {
wg.Add(1)
go createImage(i, i.OverWrite)
}
}
go func() {
wg.Wait()
e <- nil
}()
select {
case err := <-e:
return err
case <-w.Cancel:
// Wait so Images being created now will complete before we try to clean them up.
wg.Wait()
return nil
}
}