mirror of
https://github.com/moul/sshportal.git
synced 2024-11-14 12:16:42 +08:00
74 lines
1.5 KiB
Go
74 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
|
||
|
}
|