feat(agent): add mirror failover, agent client refactor, status 401 detection
- Mirror pool with health tracking and exponential backoff for failed hosts - Agent client routes requests through mirror pool with retry semantics - New `unarr mirrors` command to inspect mirror state and force failover - `unarr status` now detects 401 from /agent/register and suggests `unarr login` instead of the generic "Could not fetch account info" message - Config supports multiple ScanPaths for upcoming multi-path library scan - Draft plan for bidirectional library sync (CLI ↔ Web) under Docs/plans/
This commit is contained in:
parent
bf18812a3d
commit
a73e1a7756
12 changed files with 972 additions and 76 deletions
|
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
|
@ -58,7 +59,7 @@ func runStatus() error {
|
|||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
ac := agent.NewClient(cfg.Auth.APIURL, cfg.Auth.APIKey, "unarr/"+Version)
|
||||
ac := newAgentClientFromConfig(cfg, "unarr/"+Version)
|
||||
resp, err := ac.Register(ctx, agent.RegisterRequest{
|
||||
AgentID: cfg.Agent.ID,
|
||||
Name: cfg.Agent.Name,
|
||||
|
|
@ -74,7 +75,17 @@ func runStatus() error {
|
|||
cyan.Println(" Account")
|
||||
ar := <-accountCh
|
||||
if ar.err != nil {
|
||||
dim.Println(" Could not fetch account info")
|
||||
var httpErr *agent.HTTPError
|
||||
switch {
|
||||
case errors.As(ar.err, &httpErr) && httpErr.StatusCode == 401:
|
||||
yellow.Println(" API key invalid or revoked")
|
||||
fmt.Printf(" Run %s to re-authenticate\n", cyan.Sprint("unarr login"))
|
||||
case errors.As(ar.err, &httpErr) && httpErr.StatusCode == 403:
|
||||
yellow.Println(" API key lacks permission for this server")
|
||||
fmt.Printf(" Check plan or run %s\n", cyan.Sprint("unarr login"))
|
||||
default:
|
||||
dim.Printf(" Could not fetch account info (%v)\n", ar.err)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf(" User: %s\n", ar.user.Name)
|
||||
fmt.Printf(" Email: %s\n", ar.user.Email)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue