Exemple #1
0
// terminate the passed-in slice of hosts. returns any errors that occur
// terminating the hosts
func terminateHosts(hosts []host.Host, settings *evergreen.Settings, reason string) []error {
	errChan := make(chan error)
	for _, h := range hosts {
		evergreen.Logger.Logf(slogger.INFO, "Terminating host %v", h.Id)
		// terminate the host in a goroutine, passing the host in as a parameter
		// so that the variable isn't reused for subsequent iterations
		go func(hostToTerminate host.Host) {
			errChan <- func() error {
				event.LogMonitorOperation(hostToTerminate.Id, reason)
				err := util.RunFunctionWithTimeout(func() error {
					return terminateHost(&hostToTerminate, settings)
				}, 12*time.Minute)
				if err != nil {
					if err == util.ErrTimedOut {
						return fmt.Errorf("timeout terminating host %v", hostToTerminate.Id)
					}
					return fmt.Errorf("error terminating host %v: %v", hostToTerminate.Id, err)
				}
				evergreen.Logger.Logf(slogger.INFO, "Successfully terminated host %v", hostToTerminate.Id)
				return nil
			}()
		}(h)
	}
	var errors []error
	for range hosts {
		if err := <-errChan; err != nil {
			errors = append(errors, err)
		}
	}
	return errors
}
Exemple #2
0
// terminate the passed-in slice of hosts. returns any errors that occur
// terminating the hosts
func terminateHosts(hosts []host.Host, settings *evergreen.Settings, reason string) []error {

	// used to store any errors that occur
	var errors []error

	// for terminating the different hosts in parallel
	waitGroup := &sync.WaitGroup{}

	// to ensure thread-safe appending to the errors
	errsLock := &sync.Mutex{}

	for _, h := range hosts {

		evergreen.Logger.Logf(slogger.INFO, "Terminating host %v...", h.Id)

		waitGroup.Add(1)

		// terminate the host in a goroutine. pass the host in as a parameter
		// so that the variable isn't reused for subsequent iterations
		go func(hostToTerminate host.Host) {

			defer waitGroup.Done()

			// Log that the host was flagged, and why
			event.LogMonitorOperation(hostToTerminate.Id, reason)

			// wrapper function to terminate the host
			terminateFunc := func() error {
				return terminateHost(&hostToTerminate, settings)
			}

			// run the function with a timeout
			err := util.RunFunctionWithTimeout(terminateFunc, 10*time.Second)

			if err == util.ErrTimedOut {
				errsLock.Lock()
				errors = append(errors, fmt.Errorf("timeout terminating host %v", hostToTerminate.Id))
				errsLock.Unlock()
			} else if err != nil {
				errsLock.Lock()
				errors = append(errors, fmt.Errorf("error terminating host: %v", err))
				errsLock.Unlock()
			} else {
				evergreen.Logger.Logf(slogger.INFO, "Successfully terminated host %v", hostToTerminate.Id)
			}

		}(h)
	}

	// make sure all terminations finish
	waitGroup.Wait()

	return errors
}