77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.asio.asia/nixevol/NixMsg/internal/config"
|
|
)
|
|
|
|
// healthcheck 请求本机 /healthz,成功退出 0。给 Docker HEALTHCHECK 用。
|
|
func cmdHealthcheck(_ []string) error {
|
|
cfgPath := config.PathFromEnv()
|
|
cfg, err := config.Load(cfgPath)
|
|
if err != nil {
|
|
// 无配置时仍尝试 data_dir 默认值下的 listen.addr
|
|
cfg = config.Default()
|
|
}
|
|
addr, err := resolveHealthAddr(cfg.DataDir, cfg.Listen)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
url := "http://" + addr + "/healthz"
|
|
client := &http.Client{Timeout: 3 * time.Second}
|
|
resp, err := client.Get(url)
|
|
if err != nil {
|
|
return fmt.Errorf("healthcheck %s: %w", url, err)
|
|
}
|
|
defer func() { _ = resp.Body.Close() }()
|
|
_, _ = io.Copy(io.Discard, resp.Body)
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("healthcheck %s: status %d", url, resp.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func resolveHealthAddr(dataDir, listen string) (string, error) {
|
|
path := filepath.Join(dataDir, "listen.addr")
|
|
if b, err := os.ReadFile(path); err == nil {
|
|
addr := strings.TrimSpace(string(b))
|
|
if addr != "" {
|
|
return rewriteLoopback(addr), nil
|
|
}
|
|
}
|
|
if listen == "" {
|
|
return "", fmt.Errorf("no listen.addr and empty listen")
|
|
}
|
|
host, port, err := net.SplitHostPort(listen)
|
|
if err != nil {
|
|
// listen 可能是 ":7443"
|
|
if strings.HasPrefix(listen, ":") {
|
|
return "127.0.0.1" + listen, nil
|
|
}
|
|
return "", fmt.Errorf("parse listen %q: %w", listen, err)
|
|
}
|
|
if host == "" || host == "0.0.0.0" || host == "::" {
|
|
host = "127.0.0.1"
|
|
}
|
|
return net.JoinHostPort(host, port), nil
|
|
}
|
|
|
|
func rewriteLoopback(addr string) string {
|
|
host, port, err := net.SplitHostPort(addr)
|
|
if err != nil {
|
|
return addr
|
|
}
|
|
if host == "" || host == "0.0.0.0" || host == "::" {
|
|
host = "127.0.0.1"
|
|
}
|
|
return net.JoinHostPort(host, port)
|
|
}
|