chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user