func()

in step_delete_resources.go [256:405]


func (d *DeleteResources) run(ctx context.Context, s *Step) DError {
	var wg sync.WaitGroup
	w := s.w
	e := make(chan DError)

	for _, i := range d.Instances {
		wg.Add(1)
		go func(i string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting instance %q.", i)
			if err := w.instances.delete(i); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting instance %q: %v", i, err)
					return
				}
				e <- err
			}
		}(i)
	}

	for _, i := range d.Images {
		wg.Add(1)
		go func(i string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting image %q.", i)
			if err := w.images.delete(i); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting image %q: %v", i, err)
					return
				}
				e <- err
			}
		}(i)
	}

	for _, i := range d.MachineImages {
		wg.Add(1)
		go func(i string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting machine image %q.", i)
			if err := w.machineImages.delete(i); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting machine image %q: %v", i, err)
					return
				}
				e <- err
			}
		}(i)
	}

	for _, p := range d.GCSPaths {
		wg.Add(1)
		go func(p string) {
			defer wg.Done()
			bkt, obj, err := splitGCSPath(p)
			if err != nil {
				e <- err
				return
			}

			if obj == "" || strings.HasSuffix(obj, "/") {
				if err := recursiveGCSDelete(ctx, s.w, bkt, obj); err != nil {
					e <- err
				}
				return
			}

			if err := w.StorageClient.Bucket(bkt).Object(obj).Delete(ctx); err != nil {
				if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusNotFound {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting GCS Path %q: %v", p, err)
					return
				}
				e <- Errf("error deleting GCS path %q: %v", p, err)
			}
		}(p)
	}

	if abort, ret := waitGroup(&wg, e, w); abort {
		return ret
	}

	// Delete disks only after instances have been deleted.
	e = make(chan DError)
	for _, d := range d.Disks {
		wg.Add(1)
		go func(d string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting disk %q.", d)
			if err := w.disks.delete(d); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting disk %q: %v", d, err)
					return
				}
				e <- err
			}
		}(d)
	}

	// Delete firewalls after instance have been deleted
	for _, n := range d.Firewalls {
		wg.Add(1)
		go func(n string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting firewall %q.", n)
			if err := w.firewallRules.delete(n); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting firewall %q: %v", n, err)
				}
				e <- err
			}
		}(n)
	}

	// Delete subnetworks after firewalls.
	for _, sn := range d.Subnetworks {
		wg.Add(1)
		go func(sn string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting subnetwork %q.", sn)
			if err := w.subnetworks.delete(sn); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting subnetwork %q: %v", sn, err)
				}
				e <- err
			}
		}(sn)
	}

	if abort, ret := waitGroup(&wg, e, w); abort {
		return ret
	}

	// Delete networks after subnetworks have been deleted
	for _, n := range d.Networks {
		wg.Add(1)
		go func(n string) {
			defer wg.Done()
			w.LogStepInfo(s.name, "DeleteResources", "Deleting network %q.", n)
			if err := w.networks.delete(n); err != nil {
				if err.etype() == resourceDNEError {
					w.LogStepInfo(s.name, "DeleteResources", "WARNING: Error deleting network %q: %v", n, err)
				}
				e <- err
			}
		}(n)
	}

	_, ret := waitGroup(&wg, e, w)
	return ret
}