func()

in updater/aws.go [421:468]


func (u *updater) sendCommand(instanceIDs []string, ssmDocument string) (string, error) {
	log.Printf("Sending SSM document %q", ssmDocument)
	resp, err := u.ssm.SendCommand(&ssm.SendCommandInput{
		DocumentName:    aws.String(ssmDocument),
		DocumentVersion: aws.String("$DEFAULT"),
		InstanceIds:     aws.StringSlice(instanceIDs),
		TimeoutSeconds:  aws.Int64(deliveryTimeoutSeconds),
	})
	if err != nil {
		return "", fmt.Errorf("send command failed: %w", err)
	}
	commandID := *resp.Command.CommandId
	log.Printf("SSM document %q posted with command id %q", ssmDocument, commandID)

	// Wait for the sent commands to complete.
	wg := sync.WaitGroup{}
	instanceCount := len(instanceIDs)
	errChan := make(chan error, instanceCount)
	for _, v := range instanceIDs {
		log.Printf("Waiting for command %q to complete for instance %q", commandID, v)
		wg.Add(1)
		go func(instanceID string) {
			defer wg.Done()
			err = u.ssm.WaitUntilCommandExecutedWithContext(aws.BackgroundContext(), &ssm.GetCommandInvocationInput{
				CommandId:  aws.String(commandID),
				InstanceId: aws.String(instanceID),
			},
				request.WithWaiterMaxAttempts(waiterMaxAttempts),
				request.WithWaiterDelay(request.ConstantWaiterDelay(waiterDelay)))
			if err != nil {
				errChan <- err
				log.Printf("Error encountered while awaiting document %q execution for instance: %q: %s", ssmDocument, instanceID, err)
				u.logCommmandOutput(commandID, instanceID)
			}
		}(aws.StringValue(&v))
	}
	wg.Wait()
	close(errChan)

	errCount := 0
	for err = range errChan {
		errCount++
		if errCount == instanceCount {
			return "", fmt.Errorf("too many failures while awaiting document execution: %w", err)
		}
	}
	return commandID, nil
}