func()

in step_update_instances_metadata.go [63:118]


func (c *UpdateInstancesMetadata) run(ctx context.Context, s *Step) DError {
	var wg sync.WaitGroup
	w := s.w
	e := make(chan DError)
	for _, sm := range *c {
		wg.Add(1)
		go func(sm *UpdateInstanceMetadata) {
			defer wg.Done()

			inst := sm.Instance
			if instRes, ok := w.instances.get(sm.Instance); ok {
				inst = instRes.link
				sm.Instance = instRes.RealName
			}

			// Get metadata fingerprint and original metadata
			resp, err := w.ComputeClient.GetInstance(sm.project, sm.zone, sm.Instance)
			if err != nil {
				e <- newErr("failed to get instance data", err)
				return
			}
			metadata := compute.Metadata{}
			metadata.Fingerprint = resp.Metadata.Fingerprint
			for k, v := range sm.Metadata {
				vCopy := v
				metadata.Items = append(metadata.Items, &compute.MetadataItems{Key: k, Value: &vCopy})
			}

			for _, item := range resp.Metadata.Items {
				// Put only keys that were not updated
				if _, ok := sm.Metadata[item.Key]; !ok {
					metadata.Items = append(metadata.Items, item)
				}
			}

			w.LogStepInfo(s.name, "UpdateInstancesMetadata", "Set Instance %q metadata to %q.", inst, sm.Metadata)
			if err := w.ComputeClient.SetInstanceMetadata(sm.project, sm.zone, sm.Instance, &metadata); err != nil {
				e <- newErr("failed to set instance metadata", err)
				return
			}
		}(sm)
	}

	go func() {
		wg.Wait()
		e <- nil
	}()

	select {
	case err := <-e:
		return err
	case <-w.Cancel:
		wg.Wait()
		return nil
	}
}