a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
176 lines
5.3 KiB
Go
176 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/jedib0t/go-pretty/v6/table"
|
|
"github.com/jedib0t/go-pretty/v6/text"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/zzet/gortex/internal/daemon"
|
|
)
|
|
|
|
var (
|
|
daemonServerAddURL string
|
|
daemonServerAddDefault bool
|
|
daemonServerAddAuthToken string
|
|
daemonServerAddAuthTokenEnv string
|
|
daemonServerAddWorkspaces []string
|
|
daemonServerAddReadOnly bool
|
|
)
|
|
|
|
var daemonServerCmd = &cobra.Command{
|
|
Use: "server",
|
|
Short: "Manage the multi-server roster in ~/.gortex/servers.toml",
|
|
Long: `Maintain ~/.gortex/servers.toml — the multi-server roster the daemon
|
|
and the gortex server load on startup to wire up local-fast-path vs
|
|
proxy routing.
|
|
|
|
The file holds one [[server]] block per reachable Gortex server: a
|
|
local socket, a remote HTTPS endpoint, etc. Adding or removing an entry
|
|
is applied to a running daemon live (no restart); if the daemon is down
|
|
the change simply takes effect on its next start.`,
|
|
}
|
|
|
|
var daemonServerAddCmd = &cobra.Command{
|
|
Use: "add <slug>",
|
|
Short: "Add a server entry to ~/.gortex/servers.toml",
|
|
Long: `Append a new server to the roster. Slug must be unique. URL accepts
|
|
http://, https://, or unix:///path/to.sock. Auth: pass --auth-token-env
|
|
(preferred) to point at an environment variable, or --auth-token to
|
|
write the literal value into the file.
|
|
|
|
If --default is set and another entry already has default=true, the
|
|
command fails — remove or unflag the existing default first.`,
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: runDaemonServerAdd,
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
var daemonServerRemoveCmd = &cobra.Command{
|
|
Use: "remove <slug>",
|
|
Aliases: []string{"rm"},
|
|
Short: "Remove a server entry from ~/.gortex/servers.toml",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: runDaemonServerRemove,
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
var daemonServerListCmd = &cobra.Command{
|
|
Use: "list",
|
|
Short: "Print the current ~/.gortex/servers.toml roster",
|
|
RunE: runDaemonServerList,
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
func init() {
|
|
daemonServerAddCmd.Flags().StringVar(&daemonServerAddURL, "url", "", "server URL (http://, https://, or unix:///path) — required")
|
|
daemonServerAddCmd.Flags().BoolVar(&daemonServerAddDefault, "default", false, "mark this entry as the default server")
|
|
daemonServerAddCmd.Flags().StringVar(&daemonServerAddAuthToken, "auth-token", "", "literal bearer token (consider --auth-token-env instead)")
|
|
daemonServerAddCmd.Flags().StringVar(&daemonServerAddAuthTokenEnv, "auth-token-env", "", "env-var name the daemon reads at request time")
|
|
daemonServerAddCmd.Flags().StringSliceVar(&daemonServerAddWorkspaces, "workspaces", nil, "pre-declared workspace slugs (comma-separated)")
|
|
daemonServerAddCmd.Flags().BoolVar(&daemonServerAddReadOnly, "read-only", false, "mark this remote read-only (no write tools routed to it)")
|
|
_ = daemonServerAddCmd.MarkFlagRequired("url")
|
|
|
|
daemonServerCmd.AddCommand(daemonServerAddCmd)
|
|
daemonServerCmd.AddCommand(daemonServerRemoveCmd)
|
|
daemonServerCmd.AddCommand(daemonServerListCmd)
|
|
daemonCmd.AddCommand(daemonServerCmd)
|
|
}
|
|
|
|
func runDaemonServerAdd(_ *cobra.Command, args []string) error {
|
|
slug := args[0]
|
|
cfg, err := daemon.LoadServersConfig("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if cfg == nil {
|
|
cfg = &daemon.ServersConfig{}
|
|
}
|
|
entry := daemon.ServerEntry{
|
|
Slug: slug,
|
|
URL: daemonServerAddURL,
|
|
AuthToken: daemonServerAddAuthToken,
|
|
AuthTokenEnv: daemonServerAddAuthTokenEnv,
|
|
Workspaces: daemonServerAddWorkspaces,
|
|
Default: daemonServerAddDefault,
|
|
ReadOnly: daemonServerAddReadOnly,
|
|
}
|
|
if err := cfg.AddServer(entry); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.Save(""); err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintf(os.Stderr, "[gortex] added server %q (%s) to %s\n", slug, daemonServerAddURL, daemon.ServersConfigPath())
|
|
proxyApplyToRunningDaemon()
|
|
return nil
|
|
}
|
|
|
|
func runDaemonServerRemove(_ *cobra.Command, args []string) error {
|
|
slug := args[0]
|
|
cfg, err := daemon.LoadServersConfig("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if cfg == nil {
|
|
cfg = &daemon.ServersConfig{}
|
|
}
|
|
removed, err := cfg.RemoveServer(slug)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !removed {
|
|
fmt.Fprintf(os.Stderr, "[gortex] no server with slug %q in %s — nothing to remove\n", slug, daemon.ServersConfigPath())
|
|
return nil
|
|
}
|
|
if err := cfg.Save(""); err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintf(os.Stderr, "[gortex] removed server %q from %s\n", slug, daemon.ServersConfigPath())
|
|
proxyApplyToRunningDaemon()
|
|
return nil
|
|
}
|
|
|
|
func runDaemonServerList(_ *cobra.Command, _ []string) error {
|
|
cfg, err := daemon.LoadServersConfig("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if cfg == nil || len(cfg.Server) == 0 {
|
|
fmt.Fprintf(os.Stderr, "[gortex] no servers configured (%s is empty or missing)\n", daemon.ServersConfigPath())
|
|
return nil
|
|
}
|
|
t := table.NewWriter()
|
|
t.SetOutputMirror(os.Stdout)
|
|
t.SetStyle(table.StyleLight)
|
|
t.Style().Format.Header = text.FormatDefault
|
|
t.AppendHeader(table.Row{"slug", "url", "default", "auth", "workspaces"})
|
|
yesno := func(b bool) string {
|
|
if b {
|
|
return "yes"
|
|
}
|
|
return ""
|
|
}
|
|
for _, s := range cfg.Server {
|
|
auth := ""
|
|
switch {
|
|
case s.AuthTokenEnv != "":
|
|
auth = "env:" + s.AuthTokenEnv
|
|
case s.AuthToken != "":
|
|
auth = "literal"
|
|
}
|
|
t.AppendRow(table.Row{
|
|
s.Slug,
|
|
s.URL,
|
|
yesno(s.Default),
|
|
auth,
|
|
strings.Join(s.Workspaces, ", "),
|
|
})
|
|
}
|
|
t.Render()
|
|
return nil
|
|
}
|