Documentation
¶
Index ¶
- Variables
- func Execute() error
- func GetRoot() *cobra.Command
- func NewGapidRoot(start func(*cobra.Command, []string) error) (*cobra.Command, *DaemonFlags, *GapidStartFlags)
- func RunRoot(root *cobra.Command, args []string) error
- type ControlFlags
- type DaemonFlags
- type GapidStartFlags
- type LocalController
Constants ¶
This section is empty.
Variables ¶
var ErrNoCommand = errors.New("no command given")
ErrNoCommand is returned when a root is invoked with no subcommand. The contract requires help plus a NON-ZERO exit, and cobra cannot deliver that on its own: a root with no RunE returns flag.ErrHelp from execute(), and ExecuteC catches it, prints help and returns nil, so the process exits 0.
The obvious fix - give the root a RunE that errors - is exactly what GAPI-DIV-057 forbids, because any root RunE restores cobra's pass-through and a mistyped subcommand becomes a positional argument again. So the bare-invocation case is handled OUTSIDE Execute.
Functions ¶
func Execute ¶
func Execute() error
Execute runs the root command. Bare invocation prints help and returns ErrNoCommand so the process exits non-zero (cli-contract.md).
This is where gapictl declares its product, because this is where gapictl's PROCESS begins - package initialization is not that point, since goblinctl runs it too. Set before RunRoot: every control verb resolves config through controlConfig(), which reads the environment namespace and the search path (GAPI-DIV-061).
func NewGapidRoot ¶
func NewGapidRoot(start func(*cobra.Command, []string) error) (*cobra.Command, *DaemonFlags, *GapidStartFlags)
NewGapidRoot builds gapid's root here rather than in package main, so a test can construct it. That is not incidental tidiness: GAPI-DIV-058 is closed by comparing each root's persistent set against the shared registrar, and a root declared as a package-level var inside main is unreachable from any test.
The start action is a parameter, so this package still never imports core/supervisor.
func RunRoot ¶
RunRoot executes root against args, returning ErrNoCommand when no subcommand was named. Callers exit non-zero on any error.
This exists as a function rather than a few lines in main() so the behaviour is testable: main() is not importable, and "bare invocation exits non-zero" is a contract clause that needs a gate.
Types ¶
type ControlFlags ¶
ControlFlags holds the values bound by RegisterControlFlags: which daemon to talk to and how to reach it.
func NewControlRoot ¶
func NewControlRoot(productName, name, version, short string) (*cobra.Command, *ControlFlags)
NewControlRoot builds a control root: no RunE, a version surface, and the persistent control flags. A control binary never starts a daemon, so it gains no start verb here or anywhere.
productName carries the same meaning and the same requirement as on NewDaemonRoot: a control binary resolves the same config file and the same environment namespace as its daemon, so it must agree about which product it is.
func NewGapictlRoot ¶
func NewGapictlRoot() (*cobra.Command, *ControlFlags)
NewGapictlRoot builds a fresh gapictl root, declaring the product. Exported so the parity test can construct one without depending on package initialization order.
The orchestrator embeds this tree through GetRoot(), NOT through this constructor: goblinctl mounting the kernel's verbs under `agent` is not goblinctl becoming gapi.
func RegisterControlFlags ¶
func RegisterControlFlags(cmd *cobra.Command) *ControlFlags
RegisterControlFlags binds the control root's persistent set to cmd.
--api-addr defaults to EMPTY rather than to a literal address: the two daemons listen on different ports, so a shared default would have to be wrong for one of them. Empty means "resolve from config", which keeps config the source of truth and the flag an override.
type DaemonFlags ¶
type DaemonFlags struct {
ID string
LogLevel string
LogFormat string
LogFile string
LogLokiURL string
MetricsAddr string
TLSCA string
TLSCert string
TLSKey string
}
DaemonFlags holds the values bound by RegisterDaemonFlags. These are the flags that describe the process itself - who it is, how it reports, and what identity material it serves - so they are persistent and apply to every subcommand.
func NewDaemonRoot ¶
func NewDaemonRoot(productName, name, version, short string, start func(*cobra.Command, []string) error) (*cobra.Command, *DaemonFlags)
NewDaemonRoot builds a daemon root: no RunE, a version surface, the persistent daemon flags, and a `start` subcommand carrying the run action.
The root carries NO RunE, and that is the whole point rather than a stylistic choice. A root RunE makes cobra treat every unmatched argument as a positional parameter and hand it to the daemon, so a mistyped subcommand BOOTS A SUPERVISOR instead of failing (GAPI-DIV-057; goblind reached a 2-minute timeout this way on the word "version").
start is passed in rather than defined here so this package never imports core/supervisor. That keeps the CLI shape importable by a test - and by the orchestrator, which supplies its own start action.
productName is the PRODUCT this daemon belongs to - "gapi", "goblin" - not the binary name. It is a required parameter rather than something the kernel assumes, because every host-namespaced resource the embedded kernel touches derives from it: the environment prefix, /etc/<product>, the agent search paths, the log path, the cgroup names, and the dmesg tag under --pid1 (GAPI-DIV-061). Taking it here is the compile-time half of that guarantee - an embedder cannot build a daemon root without naming itself. core/product.Name()'s panic is the other half, for an embedder that never calls this.
func RegisterDaemonFlags ¶
func RegisterDaemonFlags(cmd *cobra.Command) *DaemonFlags
RegisterDaemonFlags binds the daemon root's persistent set to cmd and returns the struct receiving the values.
On a daemon --tls-ca is SERVER-side material: the CA against which incoming peers are verified, paired with --tls-cert and --tls-key. The control binaries reuse the name for the client's trust root, which is conventional and intended - a later pass that "unifies the TLS flags" across roles would be merging two different things.
type GapidStartFlags ¶
GapidStartFlags are local to `gapid start`: they configure a run rather than describing the process, which is what keeps them off the persistent set.
type LocalController ¶
type LocalController struct {
// contains filtered or unexported fields
}
LocalController implements tui.AgentControl using a local client
func (*LocalController) FetchStatus ¶
func (l *LocalController) FetchStatus(ctx context.Context) ([]tui.AgentStatus, error)