Documentation
¶
Overview ¶
Package cmdutil pkg/cmdutil/catch.go c0-com-util
Package cmdutil pkg/cmdutil/climisc.go c0-com-util
Package cmdutil pkg/cmdutil/cmd_name.go c0-com-util
Package cmdutil pkg/cmdutil/dmsg_bootstrap.go c0-com-util
Package cmdutil pkg/cmdutil/inprocess.go c0-com-util
Package cmdutil pkg/cmdutil/keyfile.go c0-com-util
Package cmdutil pkg/cmdutil/legacy_flag_alias.go c0-com-util shared by every svc command that has been through a flag-rename. Maps historical flag spellings to their current canonical kebab-case form so any compose.yaml / systemd unit / shell wrapper that still passes the old name keeps working invisibly.
The renamed flag is registered ONCE under its current name; this normalizer rewrites the legacy form at parse time, so the legacy form doesn't appear in --help (no surface area pollution) but still resolves to the same target.
Package cmdutil pkg/cmdutil/service_flags.go c0-com-util
Package cmdutil pkg/cmdutil/signal_context.go c0-com-util
Package cmdutil pkg/cmdutil/signal_platform_native.go c0-com-util
Package cmdutil pkg/cmdutil/signal_unix.go c0-com-util
Package cmdutil pkg/cmdutil/skyenv.go c0-com-util
Shared SKYENV config file evaluation helpers. Used by `skywire cli config gen` and the dmsg commands.
Pre-refactor this file shelled out per-call to bash (Linux) or powershell (Windows) to expand `${VAR:-default}` and `${VAR[@]}` bash-isms against the sourced env file. The fork-per-call overhead was meaningful (a single `cli config gen` triggers ~50 of these), the bash dependency made it fragile under non-default shells, and the parallel powershell path silently differed on edge cases.
Now backed by a native Go parser in skyenv_parse.go — see that file for the exact subset of bash syntax supported.
Package cmdutil pkg/cmdutil/skyenv_parse.go c0-com-util
Native-Go parser for the SKYENV config file (/etc/skywire.conf on Linux, %ProgramData%\Skywire\skywire.conf on Windows). Replaces the previous bash-subprocess approach that called `script.Exec("bash -c 'source ${SKYENV}; printf %s')`. The bash path worked but (1) added a subshell per Skyenv* call (many called during a single `config gen`), (2) required bash on every host (Windows-side had a powershell fallback with subtly different expansion semantics), and (3) leaked the env file's secrets through ps(1) / /proc.
Scope: enough of bash variable expansion to handle what skywire's own conf template emits. Specifically:
- KEY=value plain assignment
- KEY='value' / KEY="value" single- or double-quoted
- KEY=('a' 'b' 'c') bash array literal (each element optionally quoted, whitespace-separated)
- # comment line comment (also trailing on values where the comment isn't quoted in)
- ${VAR} simple substitution
- ${VAR:-default} default-if-unset-or-empty
- ${VAR-default} default-if-unset
- ${VAR[@]} array elements (whitespace-joined for compatibility with the callers that feed the result to fmt.Sprintf %s)
- ${VAR[@]-default} array-or-default
Intentionally NOT supported (nothing in our templates uses these): command substitution `$(…)`, nested expansions, multi-line continuations, `${VAR:offset:length}`, `${VAR/pat/repl}`. Adding any of those means we're papering over a template that's drifting into bash territory — prefer fixing the template.
Package cmdutil pkg/cmdutil/stdio.go c0-com-util
Package cmdutil pkg/cmdutil/svcconfig.go c0-com-util
Package cmdutil pkg/cmdutil/sysloghook_unix.go c0-com-util
Package cmdutil pkg/cmdutil/terminal.go c0-com-util
Package cmdutil pkg/cmdutil/terminal_native.go c0-com-util
Index ¶
- Variables
- func Catch(v ...interface{})
- func CatchWithLog(log logrus.FieldLogger, msg string, v ...interface{})
- func CatchWithMsg(msg string, v ...interface{})
- func CommaSplit(s string) []string
- func Eprint(a ...any) (int, error)
- func Eprintf(format string, a ...any) (int, error)
- func Eprintln(a ...any) (int, error)
- func ExampleJSON(v interface{}) string
- func Exit(code int)
- func Fatal(v ...any)
- func Fatalf(format string, v ...any)
- func Fatalln(v ...any)
- func LegacySvcFlagNormalizer(_ *pflag.FlagSet, name string) pflag.NormalizedName
- func LevelFromString(s string) (logrus.Level, int, error)
- func LoadOrGenerateKey(path string, sk *cipher.SecKey) error
- func PKFromDmsgURL(s string) cipher.PubKey
- func Print(a ...any) (int, error)
- func Printf(format string, a ...any) (int, error)
- func Println(a ...any) (int, error)
- func RootCmdName() string
- func Run(ctx context.Context, root *cobra.Command, args []string, stdin io.Reader, ...) int
- func RunRoot(cmd *cobra.Command)
- func SignalContext(ctx context.Context, log logrus.FieldLogger) (context.Context, context.CancelFunc)
- func SkyenvArray(s, envfile string) string
- func SkyenvBool(s, envfile string) bool
- func SkyenvBoolSlice(s, envfile string) []bool
- func SkyenvDefault(s string) string
- func SkyenvInt(s, envfile string) int
- func SkyenvSlice(expr, envfile string) ([]string, error)
- func SkyenvString(s, envfile string) string
- func SkyenvStringSlice(s, envfile string) []string
- func SkyenvUint(s, envfile string) uint
- func SkyenvUintSlice(s, envfile string) []uint
- func SkyenvValue(expr, envfile string) (string, error)
- func Stderr() io.Writer
- func Stdin() io.Reader
- func Stdout() io.Writer
- func Terminal() (color bool, cols int)
- func ValidTag(tag string) error
- type DmsgBootstrap
- type DmsgBootstrapOption
- type DmsgConfig
- type ServiceFlags
- type SkyenvFile
Constants ¶
This section is empty.
Variables ¶
var ( ErrTagCannotBeEmpty = errors.New("tag cannot be empty") ErrTagHasInvalidChars = errors.New("tag can only contain alphanumeric values and underscore") ErrTagHasMisplacedUnderscores = errors.New("tag cannot start or end with an underscore or have two underscores back-to-back") ErrInvalidLogString = errors.New("failed to convert string to log level") ErrInvalidSyslogNet = errors.New("network type is unsupported for syslog") )
Associated errors.
Functions ¶
func CatchWithLog ¶
func CatchWithLog(log logrus.FieldLogger, msg string, v ...interface{})
CatchWithLog calls Fatal() on any non-nil error.
func CatchWithMsg ¶
func CatchWithMsg(msg string, v ...interface{})
CatchWithMsg panics on any non-nil error with the provided message (if any).
func CommaSplit ¶
CommaSplit splits a comma-separated string into trimmed, non-empty fields. It returns nil for an empty input. This centralizes the helper that several command packages previously copied.
func ExampleJSON ¶
func ExampleJSON(v interface{}) string
ExampleJSON renders v as indented JSON for use in CLI --help example blocks. It returns "" on a marshal error. This centralizes the helper that every deployment-service command package previously copied.
func Exit ¶ added in v1.3.101
func Exit(code int)
Exit ends the command with code: the process, or only the in-process run (Run) the calling goroutine belongs to.
func LegacySvcFlagNormalizer ¶
func LegacySvcFlagNormalizer(_ *pflag.FlagSet, name string) pflag.NormalizedName
LegacySvcFlagNormalizer is the NormalizeFunc every svc command's FlagSet should install via Flags().SetNormalizeFunc. Maps legacy flag names from the table above to their current canonical form; falls through unchanged for everything else.
func LevelFromString ¶
LevelFromString returns a logrus.Level and syslog.Priority from a string identifier. An unrecognized (or empty) identifier yields info level plus an error naming it — never debug, which would silently make an unattended service verbose in production.
func LoadOrGenerateKey ¶
LoadOrGenerateKey loads a secret key from a file, or generates a new keypair and writes it to the file if it doesn't exist. This allows systemd services to auto-generate their identity on first run without bash workarounds.
func PKFromDmsgURL ¶
PKFromDmsgURL extracts the dmsg PK from a URL of the form `dmsg://<PK>:<port>[/path]`. Returns the zero PK when the URL is empty, malformed, or doesn't carry a valid PK in the host part. Used by callers that need the discovery's PK for dmsgfirst-style dials without forcing the operator to repeat the PK as a separate field in config.
func Run ¶ added in v1.3.101
func Run(ctx context.Context, root *cobra.Command, args []string, stdin io.Reader, stdout, stderr io.Writer) int
Run executes root with args in this process, on the given stdio, and returns the exit status a separate process of the binary would have had.
Runs may overlap, as a visor and a cli command do in one shell: each sets its stdio on the command it runs, not the root, and resets only that path's flags.
func RunRoot ¶
RunRoot executes a cobra root command and exits fatally on error. It centralizes the identical `func Execute()` wrapper that every command package (svc, apps, cli) previously copied verbatim.
func SignalContext ¶
func SignalContext(ctx context.Context, log logrus.FieldLogger) (context.Context, context.CancelFunc)
SignalContext returns a context that cancels on given syscall signals.
func SkyenvArray ¶
SkyenvArray evaluates an array expression and returns its elements joined by commas. Used by callers that feed the result to flags expecting a comma-separated list (StringVar shaped).
func SkyenvBool ¶
SkyenvBool evaluates expr and parses it as a Go bool. Unset / empty → fall back to `:-default`; unparseable → false.
func SkyenvBoolSlice ¶
SkyenvBoolSlice evaluates an array expression of "true"/"false" tokens and returns a bool slice. Any non-"true" element parses as false. An empty / unset variable returns [false] so callers that index `result[0]` don't panic.
func SkyenvDefault ¶
SkyenvDefault extracts the default value from a `${VAR:-default}` expression body. Public because some callers want to know "what would the fallback be" without actually sourcing the env file (e.g. constructing help text). The :- / - forms are handled the same way the parser handles them.
func SkyenvSlice ¶
SkyenvSlice sources `envfile` and expands an array expression into a string slice, one element per array entry.
func SkyenvString ¶
SkyenvString evaluates expr and returns the string value, falling back to the expression's `:-default` (if any) on empty / unset.
func SkyenvStringSlice ¶
SkyenvStringSlice evaluates an array expression and returns the raw elements.
func SkyenvUint ¶
SkyenvUint evaluates expr as a base-10 unsigned int.
func SkyenvUintSlice ¶
SkyenvUintSlice evaluates an array expression of base-10 unsigned integers and returns a uint slice. Unparseable elements are silently dropped.
func SkyenvValue ¶
SkyenvValue sources `envfile` and evaluates the bash expression `expr`, returning the raw string result. Errors are not used — the function is best-effort: a missing file, an unrecognized expression, etc. all return "".
func Stdout ¶ added in v1.3.101
Stdout is where the calling command writes its output: the stdout of the in-process run (Run) it belongs to, or the process's own.
func Terminal ¶
Terminal reports whether the calling command's standard output is a terminal that takes color, and its width in columns, 0 when not known. A command run in-process is asked about its own output, a shell's tab or pipe, not the process's, which may be a log or another terminal entirely.
Types ¶
type DmsgBootstrap ¶
DmsgBootstrap holds the result of bootstrapping a service's DMSG connection.
func BootstrapDmsg ¶
func BootstrapDmsg( ctx context.Context, log *logging.Logger, pk cipher.PubKey, sk cipher.SecKey, embeddedServers []disc.Entry, dmsgDisc string, dmsgDiscoveryDmsg string, dmsgServerType string, options ...DmsgBootstrapOption, ) (*DmsgBootstrap, error)
BootstrapDmsg creates a DMSG client for a service using the bootstrap priority:
- Embedded deployment config (dmsg.Prod/Test servers) — no network needed
- HTTP discovery fallback (only when dmsgDiscoveryDmsg is empty AND dmsgDisc is set) if embedded servers are empty
dmsgDiscoveryDmsg, when non-empty, switches the discovery fallback and the background refresh onto dmsg-HTTP — the http.Client used by the disc.APIClient gets its Transport wired to dmsghttp.MakeHTTPTransport, routing all discovery RPC over the dmsg client's sessions. No plain- HTTP egress occurs in this mode; dmsgDisc is ignored.
After connecting, a background goroutine refreshes the server list from discovery: dmsg-HTTP only when dmsgDiscoveryDmsg is set, otherwise dmsg-first with HTTP fallback.
type DmsgBootstrapOption ¶
type DmsgBootstrapOption func(*dmsgBootstrapOpts)
DmsgBootstrapOption customizes BootstrapDmsg. Options are additive and default to the previous behavior (default carrier preference, all advertised endpoints kept), so existing callers are unaffected.
func WithCarriers ¶
func WithCarriers(carriers ...string) DmsgBootstrapOption
WithCarriers sets the ordered dmsg CARRIER preference on the bootstrap client — how each server session's byte pipe is dialed (dmsg.CarrierWT / CarrierWS / CarrierQUIC / CarrierTCP). The first listed carrier a server advertises wins. Empty (the default) leaves dmsg's built-in preference (QUIC when advertised, else TCP).
func WithStrictCarrier ¶
func WithStrictCarrier() DmsgBootstrapOption
WithStrictCarrier strips the TCP/QUIC fallback endpoints (Address / AddressV6 / AddressUDP / AddressUDPV6) from the bootstrap server entries, so a dial over the requested carrier cannot silently fall back to another transport. Paired with WithCarriers it makes "the session came up over carrier X" authoritative — e.g. an e2e proving dmsg-over-WebTransport actually rode WebTransport rather than quietly falling back to TCP. The browser-reachable AddressWT/AddressWS endpoints are left intact.
type DmsgConfig ¶
type DmsgConfig struct {
// Discovery is the HTTP URL of the dmsg-discovery the service
// uses for its own dmsg-client lifecycle (refreshing the server
// list, registering a client entry, etc.). Empty for services
// that don't talk to a discovery (dmsg-discovery itself).
Discovery string `json:"discovery,omitempty"`
// DiscoveryDmsg is the dmsg-HTTP URL of the same discovery,
// form `dmsg://<PK>:<port>`. Used by dmsgfirst-style clients
// to dial the discovery over dmsg before falling back to HTTP.
DiscoveryDmsg string `json:"discovery_dmsg,omitempty"`
// SessionsCount is the minimum number of dmsg-server sessions
// the service should maintain. Zero leaves it to the runtime
// default (typically 0 — connect to all available servers).
SessionsCount int `json:"sessions_count,omitempty"`
// ServerType filters dmsg-servers by their declared type. Empty
// matches all. Mirrors the existing --dmsg-server-type flag.
ServerType string `json:"server_type,omitempty"`
// Servers is the static dmsg-server transit set the service
// preloads at startup. Replaces direct reads of
// dmsg.Prod.DmsgServers at runtime — operators ship a config
// file generated from the embedded keyring once and edit it as
// servers rotate, no rebuild required.
Servers []*disc.Entry `json:"servers,omitempty"`
}
DmsgConfig is the shared dmsg-related block embedded in each deployment service's config file. Mirrors the visor's `dmsg.discovery` / `dmsg.discovery_dmsg` / `dmsg.servers` shape so operators see a consistent schema across visor + every deployment service. The discovery's PK is encoded inside DiscoveryDmsg (`dmsg://<PK>:<port>`); there is no separate PK field — see PKFromDmsgURL.
Polymorphism (object vs array) is intentionally NOT supported here — deployment services don't have a multi-deployment use case the way the visor does. If that ever changes, the visor's pkg/dmsg/dmsgc.DmsgConfig is the precedent.
func (*DmsgConfig) Merge ¶ added in v1.3.98
func (d *DmsgConfig) Merge(src DmsgConfig)
Merge overlays every field src sets onto d, the way each service lays its config file over its command-line flags.
type ServiceFlags ¶
type ServiceFlags struct {
MetricsAddr string
Syslog string
SyslogNet string
LogLevel string
Tag string
Config string
Stdin bool
// contains filtered or unexported fields
}
ServiceFlags represents common flags which are shared across services.
func (*ServiceFlags) Init ¶
func (sf *ServiceFlags) Init(rootCmd *cobra.Command, defaultTag, defaultConf string)
Init initiates the service flags. The following are performed:
- Ensure 'defaultTag' is provided and valid.
- Set "library" defaults.
- Set "exec" defaults - provided by 'defaultTag' and 'defaultConf'.
- Add flags to 'rootCmd'.
func (*ServiceFlags) Logger ¶
func (sf *ServiceFlags) Logger() *logging.Logger
Logger returns the logger as specified by the service flags.
func (*ServiceFlags) ParseConfig ¶
func (sf *ServiceFlags) ParseConfig(args []string, checkArgs bool, v interface{}, genDefaultFunc func() (io.ReadCloser, error)) error
ParseConfig parses config from service tags. If checkArgs is set, we additionally parse os.Args to find a config path.
type SkyenvFile ¶
SkyenvFile is the parsed contents of a SKYENV config file. The map values carry the source-level "shape" of the assignment: scalar assignments become a single-element slice; bash array literals stay as multi-element slices so ${VAR[@]} expansion preserves element boundaries.
func ParseSkyenvFile ¶
func ParseSkyenvFile(path string) (*SkyenvFile, error)
ParseSkyenvFile reads `path` and returns a SkyenvFile. A missing path is NOT an error — callers (the cli config gen flag defaults) invoke this on every flag binding, well before any operator has edited /etc/skywire.conf. Empty result + nil err mirrors the old bash path's behavior on a missing file.
One level of SKYENV= redirect is honored: if the parsed file reassigns SKYENV to a different existing path, that file's contents are parsed second and overlay the first. Mirrors the "source twice" pattern the previous bash implementation used so operators with `/etc/skywire.conf → ~/.config/skywire.conf` redirects keep the same behavior.
func (*SkyenvFile) Eval ¶
func (f *SkyenvFile) Eval(expr string) string
Eval evaluates a single ${...} expression against f. Returns the expanded string. Mirrors the subset of bash expansion the old `script.Exec("bash -c 'printf %s' ${expr}")` path produced.
Recognized expressions:
${VAR} → value of VAR (empty if unset)
${VAR:-default} → value of VAR if set+non-empty, else default
${VAR-default} → value of VAR if set, else default
${VAR[@]} → array elements joined with space
${VAR[@]-default} → array elements if set, else default
Anything that doesn't start with `${` and end with `}` is returned verbatim — same forgiving behavior as the bash path.
func (*SkyenvFile) EvalSlice ¶
func (f *SkyenvFile) EvalSlice(expr string) []string
EvalSlice returns the array form. Unlike Eval which joins, this preserves element boundaries — used by SkyenvSlice / SkyenvStringSlice callers that need to range over the result.