98 lines
2.8 KiB
Go

package report
import (
"context"
"os"
"regexp"
"strconv"
"strings"
"time"
)
// collectAnyone gathers Anyone Protocol relay/client health information.
func collectAnyone() *AnyoneReport {
r := &AnyoneReport{}
// 1. RelayActive: systemctl is-active orama-anyone-relay
{
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if out, err := runCmd(ctx, "systemctl", "is-active", "orama-anyone-relay"); err == nil {
r.RelayActive = strings.TrimSpace(out) == "active"
}
}
// 2. ClientActive: systemctl is-active orama-anyone-client
{
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if out, err := runCmd(ctx, "systemctl", "is-active", "orama-anyone-client"); err == nil {
r.ClientActive = strings.TrimSpace(out) == "active"
}
}
// 3. Mode: derive from active state
if r.RelayActive {
r.Mode = "relay"
} else if r.ClientActive {
r.Mode = "client"
}
// 4. ORPortListening, SocksListening, ControlListening: check ports in ss -tlnp
{
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if out, err := runCmd(ctx, "ss", "-tlnp"); err == nil {
r.ORPortListening = portIsListening(out, 9001)
r.SocksListening = portIsListening(out, 9050)
r.ControlListening = portIsListening(out, 9051)
}
}
// 5. Bootstrapped / BootstrapPct: parse last "Bootstrapped" line from notices.log
{
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if out, err := runCmd(ctx, "bash", "-c",
`grep "Bootstrapped" /var/log/anon/notices.log 2>/dev/null | tail -1`); err == nil {
out = strings.TrimSpace(out)
if out != "" {
// Parse percentage from lines like:
// "... Bootstrapped 100% (done): Done"
// "... Bootstrapped 85%: Loading relay descriptors"
re := regexp.MustCompile(`Bootstrapped\s+(\d+)%`)
if m := re.FindStringSubmatch(out); len(m) >= 2 {
if pct, err := strconv.Atoi(m[1]); err == nil {
r.BootstrapPct = pct
r.Bootstrapped = pct == 100
}
}
}
}
}
// 6. Fingerprint: read /var/lib/anon/fingerprint
if data, err := os.ReadFile("/var/lib/anon/fingerprint"); err == nil {
line := strings.TrimSpace(string(data))
// The file may contain "nickname fingerprint" — extract just the fingerprint.
fields := strings.Fields(line)
if len(fields) >= 2 {
r.Fingerprint = fields[1]
} else if len(fields) == 1 {
r.Fingerprint = fields[0]
}
}
// 7. Nickname: extract from anonrc config
{
ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)
defer cancel()
if out, err := runCmd(ctx, "bash", "-c",
`grep "^Nickname" /etc/anon/anonrc 2>/dev/null | awk '{print $2}'`); err == nil {
r.Nickname = strings.TrimSpace(out)
}
}
return r
}