Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "os/exec"
- "strings"
- "sync"
- hierr "github.com/reconquest/hierr-go"
- "github.com/rs/xid"
- "github.com/sirupsen/logrus"
- )
- func checkContainers(
- containers []container,
- config *gospodiConfig,
- verbose bool,
- log *logrus.Entry,
- ) error {
- var commonErrors error
- errorsChannel := make(chan error, 1)
- commonChannel := make(chan []error, 1)
- wg := sync.WaitGroup{}
- for _, container := range containers {
- wg.Add(1)
- go checkContainer(container, config, &wg, errorsChannel, verbose, log)
- }
- go readErrorsChannel(errorsChannel, commonChannel)
- wg.Wait()
- close(errorsChannel)
- errors := <-commonChannel
- if len(errors) != 0 {
- commonErrors = fmt.Errorf("failed check services")
- for _, err := range errors {
- commonErrors = hierr.Push(commonErrors, err)
- }
- }
- return commonErrors
- }
- func checkContainer(
- container container,
- config *gospodiConfig,
- wg *sync.WaitGroup,
- channel chan error,
- verbose bool,
- log *logrus.Entry,
- ) {
- id := xid.New()
- log = log.WithFields(
- logrus.Fields{
- "goroutine_id": id,
- "container": container.name,
- "ip": container.ip,
- },
- )
- log.Debug("check container")
- var hasContainerHealthChecks bool
- defer wg.Done()
- for name, service := range config.Services {
- if strings.Contains(container.name, name) {
- hasContainerHealthChecks = true
- err := checkService(
- container, service, config.SSH, verbose, log,
- )
- if err != nil {
- channel <- hierr.Errorf(
- err,
- "[%s] failed check `%s` service for `%s` container",
- id,
- service.Name,
- container.name,
- )
- return
- }
- }
- }
- if !hasContainerHealthChecks {
- log.Warning("can't find healthcheckers")
- } else {
- log.Infof("successfully checked")
- }
- channel <- nil
- }
- func checkService(
- container container,
- service service,
- sshConfig ssh,
- verbose bool,
- log *logrus.Entry,
- ) error {
- log = log.WithField("service", service.Name)
- log.Debug("check service")
- for _, healthChecker := range service.HealthCheckers {
- command := []string{
- "-a", container.ip,
- "-p", container.port,
- "-s", sshConfig.User,
- "--ssh-port", sshConfig.Port,
- "-k", sshConfig.KeyPath,
- "-n", container.name,
- }
- if verbose {
- command = append(command, "--verbose")
- }
- log.WithField("health_checker", healthChecker).Debugf(
- "execute: `%s %s`", healthChecker, strings.Join(command, " "),
- )
- output, err := exec.Command(healthChecker, command...).CombinedOutput()
- if err != nil {
- return hierr.Errorf(
- output,
- "healthcheck %s finished with error: %v",
- healthChecker,
- err,
- )
- }
- }
- return nil
- }
- func readErrorsChannel(errorsChannel chan error, commonChannel chan []error) {
- var commonErrors []error
- for err := range errorsChannel {
- if err != nil {
- commonErrors = append(commonErrors, err)
- }
- }
- commonChannel <- commonErrors
- close(commonChannel)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement