sshportal/healthcheck.go

73 lines
1.5 KiB
Go

package main
import (
"bytes"
"fmt"
"log"
"net"
"strings"
"time"
"github.com/urfave/cli"
gossh "golang.org/x/crypto/ssh"
)
// perform a healthcheck test without requiring an ssh client or an ssh key (used for Docker's HEALTHCHECK)
func healthcheck(addr string, wait, quiet bool) error {
cfg := gossh.ClientConfig{
User: "healthcheck",
HostKeyCallback: func(hostname string, remote net.Addr, key gossh.PublicKey) error { return nil },
Auth: []gossh.AuthMethod{gossh.Password("healthcheck")},
}
if wait {
for {
if err := healthcheckOnce(addr, cfg, quiet); err != nil {
if !quiet {
log.Printf("error: %v", err)
}
time.Sleep(time.Second)
continue
}
return nil
}
}
if err := healthcheckOnce(addr, cfg, quiet); err != nil {
if quiet {
return cli.NewExitError("", 1)
}
return err
}
return nil
}
func healthcheckOnce(addr string, config gossh.ClientConfig, quiet bool) error {
client, err := gossh.Dial("tcp", addr, &config)
if err != nil {
return err
}
session, err := client.NewSession()
if err != nil {
return err
}
defer func() {
if err := session.Close(); err != nil {
if !quiet {
log.Printf("failed to close session: %v", err)
}
}
}()
var b bytes.Buffer
session.Stdout = &b
if err := session.Run(""); err != nil {
return err
}
stdout := strings.TrimSpace(b.String())
if stdout != "OK" {
return fmt.Errorf("invalid stdout: %q expected 'OK'", stdout)
}
return nil
}