mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-23 18:54:16 +00:00
`go fix` carries the modernize analyzers now, and the tree had drifted behind
them. This is the mechanical result, reviewed rather than trusted: the tool is
capable of rewriting code into something that no longer tests or does what it
did, so every non-test change was read individually and the concurrency-bearing
packages were re-run under -race.
Production code, four changes, all semantics-preserving:
- leases/manager.go: wg.Add(1) + go + defer wg.Done() becomes wg.Go. The
comment above that function turns on Add happening before the goroutine
starts, so that a Wait cannot return before the worker has run. wg.Go does
the Add synchronously on the calling goroutine, so the invariant it
describes still holds.
- auth/token/handler.go: strings.Fields -> strings.FieldsSeq, same splitting,
iterated rather than allocated.
- hold/gc/gc.go: a hand-written map copy -> maps.Copy.
- hold/pds/scan_broadcaster.go: three-clause loop -> range over int.
The rest are tests. The one worth naming is carstore_contention_test.go, where a
careless rewrite could have quietly stopped exercising contention: go fix
converted the reader and side-table goroutines to loopWG.Go but correctly
declined to touch the writer loop, which passes its index as a parameter. The
writer/reader/side-table shape and the stop channel are unchanged, so the test
still contends over the same carstore transactions.
Verified: go build for hold and appview, `make lint` 0 issues, the deploy and
credential-helper modules 0 issues, `make test` green across all 43 packages,
and -race green on leases, hold/pds, hold/gc and auth/token. The scanner module's
two lint findings are unchanged from HEAD and are in files go fix never touched.
Kept separate from the HTTP/2 commit so that one stays readable, and so this can
be reverted on its own if a modernization turns out to matter.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TA9D4DjaLZTvzQ7dJbu4eg
146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var statusCmd = &cobra.Command{
|
|
Use: "status",
|
|
Short: "Show infrastructure state and health",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
token, _ := cmd.Root().PersistentFlags().GetString("token")
|
|
return cmdStatus(token)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(statusCmd)
|
|
}
|
|
|
|
func cmdStatus(token string) error {
|
|
state, err := loadState()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
naming := state.Naming()
|
|
|
|
svc, err := newService(token)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
fmt.Printf("Zone: %s\n\n", state.Zone)
|
|
|
|
// Server status
|
|
for _, s := range []struct {
|
|
name string
|
|
ss ServerState
|
|
serviceName string
|
|
healthURL string
|
|
}{
|
|
{"Appview", state.Appview, naming.Appview(), "http://localhost:5000/health"},
|
|
{"Hold", state.Hold, naming.Hold(), "http://localhost:8080/xrpc/_health"},
|
|
} {
|
|
fmt.Printf("%-8s UUID: %s\n", s.name, s.ss.UUID)
|
|
fmt.Printf(" Public: %s\n", s.ss.PublicIP)
|
|
fmt.Printf(" Private: %s\n", s.ss.PrivateIP)
|
|
|
|
if s.ss.UUID != "" {
|
|
details, err := svc.GetServerDetails(ctx, &request.GetServerDetailsRequest{
|
|
UUID: s.ss.UUID,
|
|
})
|
|
if err != nil {
|
|
fmt.Printf(" State: error (%v)\n", err)
|
|
} else {
|
|
fmt.Printf(" State: %s\n", details.State)
|
|
}
|
|
}
|
|
|
|
// SSH health check
|
|
if s.ss.PublicIP != "" {
|
|
output, err := runSSH(s.ss.PublicIP, fmt.Sprintf(
|
|
"systemctl is-active %s 2>/dev/null || echo 'inactive'; curl -sf %s > /dev/null 2>&1 && echo 'health:ok' || echo 'health:fail'",
|
|
s.serviceName, s.healthURL,
|
|
), false)
|
|
if err != nil {
|
|
fmt.Printf(" Service: unreachable\n")
|
|
} else {
|
|
lines := strings.SplitSeq(strings.TrimSpace(output), "\n")
|
|
for line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "active" || line == "inactive" {
|
|
fmt.Printf(" Service: %s\n", line)
|
|
} else if after, ok := strings.CutPrefix(line, "health:"); ok {
|
|
fmt.Printf(" Health: %s\n", after)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
// Scanner status (runs on hold server)
|
|
if state.ScannerEnabled {
|
|
fmt.Printf("Scanner (on hold server)\n")
|
|
if state.Hold.PublicIP != "" {
|
|
output, err := runSSH(state.Hold.PublicIP, fmt.Sprintf(
|
|
"systemctl is-active %s 2>/dev/null || echo 'inactive'; curl -sf http://localhost:9090/healthz > /dev/null 2>&1 && echo 'health:ok' || echo 'health:fail'",
|
|
naming.Scanner(),
|
|
), false)
|
|
if err != nil {
|
|
fmt.Printf(" Service: unreachable\n")
|
|
} else {
|
|
lines := strings.SplitSeq(strings.TrimSpace(output), "\n")
|
|
for line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "active" || line == "inactive" {
|
|
fmt.Printf(" Service: %s\n", line)
|
|
} else if after, ok := strings.CutPrefix(line, "health:"); ok {
|
|
fmt.Printf(" Health: %s\n", after)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
// LB status
|
|
if state.LB.UUID != "" {
|
|
fmt.Printf("Load Balancer: %s\n", state.LB.UUID)
|
|
lb, err := svc.GetLoadBalancer(ctx, &request.GetLoadBalancerRequest{
|
|
UUID: state.LB.UUID,
|
|
})
|
|
if err != nil {
|
|
fmt.Printf(" State: error (%v)\n", err)
|
|
} else {
|
|
fmt.Printf(" State: %s\n", lb.OperationalState)
|
|
for _, n := range lb.Networks {
|
|
fmt.Printf(" Network (%s): %s\n", n.Type, n.DNSName)
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.Printf("\nNetwork: %s\n", state.Network.UUID)
|
|
|
|
if state.ObjectStorage.UUID != "" {
|
|
fmt.Printf("\nObject Storage: %s\n", state.ObjectStorage.UUID)
|
|
fmt.Printf(" Endpoint: %s\n", state.ObjectStorage.Endpoint)
|
|
fmt.Printf(" Region: %s\n", state.ObjectStorage.Region)
|
|
fmt.Printf(" Bucket: %s\n", state.ObjectStorage.Bucket)
|
|
fmt.Printf(" Access Key: %s\n", state.ObjectStorage.AccessKeyID)
|
|
}
|
|
|
|
return nil
|
|
}
|