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
}
}