Advertisement
Guest User

Untitled

a guest
Jun 7th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.97 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "os/exec"
  6.     "strings"
  7.     "sync"
  8.  
  9.     hierr "github.com/reconquest/hierr-go"
  10.     "github.com/rs/xid"
  11.     "github.com/sirupsen/logrus"
  12. )
  13.  
  14. func checkContainers(
  15.     containers []container,
  16.     config *gospodiConfig,
  17.     verbose bool,
  18.     log *logrus.Entry,
  19. ) error {
  20.     var commonErrors error
  21.  
  22.     errorsChannel := make(chan error, 1)
  23.     commonChannel := make(chan []error, 1)
  24.  
  25.     wg := sync.WaitGroup{}
  26.     for _, container := range containers {
  27.         wg.Add(1)
  28.         go checkContainer(container, config, &wg, errorsChannel, verbose, log)
  29.     }
  30.  
  31.     go readErrorsChannel(errorsChannel, commonChannel)
  32.  
  33.     wg.Wait()
  34.     close(errorsChannel)
  35.  
  36.     errors := <-commonChannel
  37.     if len(errors) != 0 {
  38.         commonErrors = fmt.Errorf("failed check services")
  39.         for _, err := range errors {
  40.             commonErrors = hierr.Push(commonErrors, err)
  41.         }
  42.  
  43.     }
  44.  
  45.     return commonErrors
  46. }
  47.  
  48. func checkContainer(
  49.     container container,
  50.     config *gospodiConfig,
  51.     wg *sync.WaitGroup,
  52.     channel chan error,
  53.     verbose bool,
  54.     log *logrus.Entry,
  55. ) {
  56.     id := xid.New()
  57.     log = log.WithFields(
  58.         logrus.Fields{
  59.             "goroutine_id": id,
  60.             "container":    container.name,
  61.             "ip":           container.ip,
  62.         },
  63.     )
  64.     log.Debug("check container")
  65.  
  66.     var hasContainerHealthChecks bool
  67.  
  68.     defer wg.Done()
  69.  
  70.     for name, service := range config.Services {
  71.         if strings.Contains(container.name, name) {
  72.             hasContainerHealthChecks = true
  73.  
  74.             err := checkService(
  75.                 container, service, config.SSH, verbose, log,
  76.             )
  77.             if err != nil {
  78.                 channel <- hierr.Errorf(
  79.                     err,
  80.                     "[%s] failed check `%s` service for `%s` container",
  81.                     id,
  82.                     service.Name,
  83.                     container.name,
  84.                 )
  85.                 return
  86.             }
  87.         }
  88.     }
  89.  
  90.     if !hasContainerHealthChecks {
  91.         log.Warning("can't find healthcheckers")
  92.     } else {
  93.         log.Infof("successfully checked")
  94.     }
  95.  
  96.     channel <- nil
  97. }
  98.  
  99. func checkService(
  100.     container container,
  101.     service service,
  102.     sshConfig ssh,
  103.     verbose bool,
  104.     log *logrus.Entry,
  105. ) error {
  106.     log = log.WithField("service", service.Name)
  107.     log.Debug("check service")
  108.  
  109.     for _, healthChecker := range service.HealthCheckers {
  110.         command := []string{
  111.             "-a", container.ip,
  112.             "-p", container.port,
  113.             "-s", sshConfig.User,
  114.             "--ssh-port", sshConfig.Port,
  115.             "-k", sshConfig.KeyPath,
  116.             "-n", container.name,
  117.         }
  118.  
  119.         if verbose {
  120.             command = append(command, "--verbose")
  121.         }
  122.  
  123.         log.WithField("health_checker", healthChecker).Debugf(
  124.             "execute: `%s %s`", healthChecker, strings.Join(command, " "),
  125.         )
  126.  
  127.         output, err := exec.Command(healthChecker, command...).CombinedOutput()
  128.         if err != nil {
  129.             return hierr.Errorf(
  130.                 output,
  131.                 "healthcheck %s finished with error: %v",
  132.                 healthChecker,
  133.                 err,
  134.             )
  135.         }
  136.     }
  137.  
  138.     return nil
  139. }
  140.  
  141. func readErrorsChannel(errorsChannel chan error, commonChannel chan []error) {
  142.     var commonErrors []error
  143.  
  144.     for err := range errorsChannel {
  145.         if err != nil {
  146.             commonErrors = append(commonErrors, err)
  147.         }
  148.     }
  149.  
  150.     commonChannel <- commonErrors
  151.     close(commonChannel)
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement