Documentation
¶
Overview ¶
Package services pkg/services/common.go c2-vis-appsvc
Package services pkg/services/cxo.go c2-vis-appsvc
Package services pkg/services/duration.go c2-vis-appsvc
Duration is a time.Duration wrapper that JSON-marshals as a Go duration string ("2m", "30s", "100ms") and unmarshals from either a string or a number (nanoseconds). Standard time.Duration's JSON support is asymmetric — it marshals as a number but won't unmarshal a string, so config files using human-readable durations fail to parse without a wrapper like this.
Mirrored from pkg/visor/visorconfig.Duration so the deployment services can use it without importing the whole visorconfig package (which would broaden their dependency surface for one type).
Package services pkg/services/embed.go c2-vis-appsvc
Embedding: a service that can run inside a host process which already owns a dmsg client and an identity. The host (the visor) mounts the service's HTTP handler under a path prefix on its own dmsg HTTP port, so the service is addressed as dmsg://<host pk>:80/<prefix>/... and needs no key, no listener and no dmsg sessions of its own. Its CXO work runs on the host's client under the host's key.
Package services pkg/services/flags.go c2-vis-appsvc
Package services pkg/services/keyfile.go c4-net-discovery
Package services pkg/services/listen.go c2-vis-appsvc
The startup steps every discovery-type service shares: its dmsg identity, its HTTP and dmsghttp listeners, its charts page, and its run loop.
Package services pkg/services/loglevel.go c2-vis-appsvc
Per-service log levels.
Every service block may carry its own "log_level". Historically each service applied it by calling the package-global logging.SetLevel, which is fine for a single-service binary (`skywire svc ar`) but wrong under `skywire svc run`, where several services share one process: the last service constructed decided the level for every other service, so a per-service log_level was misleading and one block set to "debug" turned on debug logging for the whole process.
NewLogger keeps the single-service behavior exactly as it was and gives each service its own independently-leveled logger when the process hosts more than one.
Package services pkg/services/run.go c2-vis-appsvc
errgroup-style supervisor for a parsed services.File. Brought into its own file so the registry primitives in services.go stay small and easy to read.
Package services pkg/services/services.go c2-vis-appsvc
Multi-service-in-one-process runner for Skywire deployment services. Each service registers a Factory that decodes its block from a JSON services.json and returns a Service that runs until ctx cancels or a fatal error.
Goal: collapse the nine deployment-side containers exercised by CI e2e (dmsg-discovery, dmsg-server, transport-discovery, service-discovery, address-resolver, route-finder, transport-setup, stun-server, setup-node) down to a single binary invocation (`skywire svc run --config services.json`) so CI e2e doesn't have to wrangle nine Dockerfiles. Production deployments unchanged — the existing per-service cobra subcommands stay and build their own Service via the same Factory.
Topology choice: each service gets its own HTTP listener (no path multiplexing). In-process topology stays identical to the multi-container topology, so the e2e suite exercises the same code paths whether it runs collapsed or not.
Package services pkg/services/state.go c2-vis-appsvc
Index ¶
- Constants
- func ConfigPubKey(raw json.RawMessage) cipher.PubKey
- func ConsumeSystemFeed(ctx context.Context, log *logging.Logger, pk cipher.PubKey, ...)
- func DmsgDiscEntries(servers []*disc.Entry) []disc.Entry
- func DmsgDiscovery(cfg cmdutil.DmsgConfig) string
- func MergeCommon(dst *Common, src Common)
- func Mount(mux *http.ServeMux, prefix string, handler http.Handler)
- func NewLogger(tag, level string) *logging.Logger
- func NonceStoreType(store storeconfig.Type, plainHTTP bool) storeconfig.Type
- func OpenChartsStore(sc storeconfig.Config, prefix string, log *logging.Logger) charts.Store
- func OwnKey(raw json.RawMessage) (resolved json.RawMessage, pk cipher.PubKey, ok bool, err error)
- func Register(svcType string, f Factory)
- func RegisteredTypes() []string
- func Run(ctx context.Context, file File, master *logging.MasterLogger) error
- func ServeCharts(ctx context.Context, addr string, page http.HandlerFunc, log *logging.Logger, ...)
- func SharedProcess()
- func StoreKind(t storeconfig.Type) string
- func Wait(ctx context.Context, h *svcmode.Handle, log *logging.Logger) error
- type Aggregator
- type AggregatorState
- type Block
- type CXOAggregating
- type CXOHost
- type CXOSet
- type ChartsPager
- type Common
- func (c *Common) Identity(log *logging.Logger) Identity
- func (c *Common) Listen(ctx context.Context, id Identity, l Listener, log *logging.Logger) (*svcmode.Handle, error)
- func (c *Common) LogTag(def string) string
- func (c *Common) NonceStoreConfig(plainHTTP bool) storeconfig.Config
- func (c *Common) PoolSize() int
- func (c *Common) RedisURL() string
- func (c *Common) StartPprof(log *logging.Logger) (stop func())
- func (c *Common) StoreConfig() storeconfig.Config
- func (c *Common) StoreType() storeconfig.Type
- func (c *Common) SurveyKeys() []cipher.PubKey
- type Duration
- type Embeddable
- type Factory
- type File
- type FlagDefaults
- type Flags
- type Host
- type Identity
- type Listener
- type Publisher
- type PublisherState
- type Service
- type State
- type Stater
Constants ¶
const DefaultPprofAddr = "localhost:6060"
DefaultPprofAddr is where http profiling serves when no address is set.
const DefaultRedisPoolSize = 10
DefaultRedisPoolSize is the pool size when RedisPoolSize is unset.
Variables ¶
This section is empty.
Functions ¶
func ConfigPubKey ¶ added in v1.3.100
func ConfigPubKey(raw json.RawMessage) cipher.PubKey
ConfigPubKey returns the public key a block names inline or in the file its "config_path" points at, or a null key.
func ConsumeSystemFeed ¶
func ConsumeSystemFeed(ctx context.Context, log *logging.Logger, pk cipher.PubKey, c cxoaggregate.FeedConsumer)
ConsumeSystemFeed registers c to take its registrations off the visors' system feeds that a transport discovery in this process aggregates, until ctx ends. Outside such a process it receives nothing.
func DmsgDiscEntries ¶
DmsgDiscEntries is the dmsg servers the service bootstraps from: the configured ones, or the deployment's when none are set.
func DmsgDiscovery ¶
func DmsgDiscovery(cfg cmdutil.DmsgConfig) string
DmsgDiscovery is the dmsg discovery address of cfg, the deployment's when unset. Discovery is reached over dmsg only.
func MergeCommon ¶ added in v1.3.98
MergeCommon overlays every field src sets onto dst. A service's config file overlays its command-line flags with it, so a key means the same thing in every service's file.
func Mount ¶ added in v1.3.98
Mount attaches handler under prefix on mux: a request for prefix/health reaches handler as /health. A request for the bare prefix is redirected to prefix/ by the mux.
func NewLogger ¶
NewLogger returns the logger a service should log through, given the "log_level" from its own config block and the tag it logs under.
An empty level leaves everything alone. An unparseable one is reported at warn — naming the offending string and the level actually used — and falls back to info, so a typo in a config file can no longer put a production service into debug without saying so.
When this process hosts a single service, the level is applied to the process-global master logger as before, so library packages (dmsg, httpauth, the stores) are quieted along with the service. When several services share the process, the level applies to the returned logger only; Run separately picks the shared global level from all the blocks.
func NonceStoreType ¶ added in v1.3.98
func NonceStoreType(store storeconfig.Type, plainHTTP bool) storeconfig.Type
NonceStoreType is where auth nonces live. Requests over dmsg are authenticated by the stream's key and never consult nonces, so only a plain-HTTP surface needs them durable: redis when one is served and the store is redis, memory otherwise. Every service keeps a nonce store: its clients fetch a nonce before their first request.
func OpenChartsStore ¶
OpenChartsStore keeps chart samples in the service's redis under prefix, or in memory when the store is not redis or redis is unavailable.
func OwnKey ¶ added in v1.3.100
func OwnKey(raw json.RawMessage) (resolved json.RawMessage, pk cipher.PubKey, ok bool, err error)
OwnKey resolves a block's "keyfile" the way the services runner does and returns the block with its key filled in, plus the public key it names. ok is false for a block that names no key.
func Register ¶
Register installs a Factory for the given service type. Called from each service package's init(); duplicate registrations panic (programmer error, caught at process startup).
func RegisteredTypes ¶
func RegisteredTypes() []string
RegisteredTypes returns the sorted list of currently-registered service types. Used by the cobra subcommand's error messages and `skywire svc run --list` output.
func Run ¶
Run dispatches every block in file to its registered Factory and supervises the resulting Services. Returns when:
- ctx is canceled (returns nil)
- SIGINT/SIGTERM is received (returns nil; ctx is canceled internally so all services unwind cleanly)
- any service's Run returns an error (returns the first error; other services are then canceled and joined)
Each service runs in its own goroutine and shares the same ctx. Services log under their Block.Label() so an operator looking at merged stdout can tell two instances of the same service type apart.
func ServeCharts ¶
func ServeCharts(ctx context.Context, addr string, page http.HandlerFunc, log *logging.Logger, extra ...charts.Extra)
ServeCharts serves page alone on addr until ctx ends. An empty addr does nothing.
func SharedProcess ¶ added in v1.3.100
func SharedProcess()
SharedProcess tells the services that their process hosts more than them, such as a visor, so a block's log_level stays scoped to that block.
func StoreKind ¶ added in v1.3.98
func StoreKind(t storeconfig.Type) string
StoreKind names a store type for State.
Types ¶
type Aggregator ¶ added in v1.3.98
type Aggregator interface {
Run(ctx context.Context)
Close() error
Stats() cxoaggregate.Stats
Ingest(r *cxoregistry.Root)
}
Aggregator is a CXO fan-in aggregator (the cxoaggregate-based ones in dmsg-discovery, the address resolver, service discovery and transport discovery all satisfy it).
type AggregatorState ¶ added in v1.3.98
type AggregatorState struct {
// Name says what the visors publish on this port.
Name string `json:"name"`
Port uint16 `json:"port"`
// publisher node for this port instead of a node of its own.
Shared bool `json:"shared"`
// Conns are the visor connections on the node; Subscribed of them
// carry a subscription to the visor's feed.
Conns int `json:"conns"`
Subscribed int `json:"subscribed"`
// Feeds held in the node's store, the host's own included.
Feeds int `json:"feeds"`
// LocalRoots counts Roots taken from the host's own publisher.
LocalRoots uint64 `json:"local_roots,omitempty"`
// Consumers are the services in this process taking registrations off the
// visors' system feeds through this aggregator; Delivered counts handoffs.
Consumers []string `json:"consumers,omitempty"`
Delivered uint64 `json:"delivered,omitempty"`
// Error is why the aggregator is not running, if it is not.
Error string `json:"error,omitempty"`
}
AggregatorState describes one CXO aggregator.
type Block ¶
type Block struct {
Type string
Name string
Raw json.RawMessage
// LogLevel is the block's optional "log_level", read here so the
// supervisor can pick a shared level for the library packages
// before any service is built. Each factory still reads its own.
LogLevel string
}
Block is one service entry. UnmarshalJSON pulls the type marker out and stashes the full block bytes on Raw for the factory.
func (*Block) Label ¶
Label returns the operator-visible name for this block, falling back to the type when no explicit name was set. Used in log prefixes so an operator running multiple instances of the same service type can tell them apart.
func (Block) MarshalJSON ¶ added in v1.3.98
MarshalJSON writes the block back exactly as it was read, so a config that carries service blocks survives a load-and-save round trip.
func (*Block) Prefix ¶ added in v1.3.98
Prefix returns the path prefix the block is mounted under: its "prefix" field, or the default for its type, or "/<type>". Always starts with "/" and never ends with one.
func (*Block) UnmarshalJSON ¶
UnmarshalJSON captures both the typed fields ("type", optional "name") and the full block bytes, so factories can re-decode the block into their own config struct. Forward-compatible: extra service-specific fields live alongside "type" / "name" in the same object and reach the factory via Raw.
type CXOAggregating ¶ added in v1.3.98
type CXOAggregating interface {
AggregatorPorts() []uint16
}
CXOAggregating is implemented by services that aggregate CXO feeds. A host that embeds one keeps its own publishers on these ports in memory and lends them to the service (see CXOHost).
type CXOHost ¶ added in v1.3.98
type CXOHost interface {
// CXONode returns the host's node listening on port, or nil when the
// host publishes nothing there.
CXONode(port uint16) *node.Node
// OnLocalRoot registers fn to receive every Root the host publishes
// on port, starting with the current one.
OnLocalRoot(port uint16, fn func(*cxoregistry.Root))
}
CXOHost is the host's CXO publishing, lent to an embedded service. A service aggregates a feed on the same DMSG port visors publish it on, and its host is a visor publishing on that port too, under the same key. A port takes one listener, so the service's aggregator runs on the host's node for that port, and the host's own feed, which no peer delivers to its own node, is handed over in-process.
type CXOSet ¶ added in v1.3.98
type CXOSet struct {
// Stats, when set, names each feed's port on the status page.
Stats interface {
NamePort(port uint16, name string)
}
// contains filtered or unexported fields
}
CXOSet is one service's CXO aggregators and publishers. It starts them the same way in every service, on the host's nodes where the host lends them, closes them when the service stops, and reports them in State.
func (*CXOSet) AddPublisher ¶ added in v1.3.98
func (s *CXOSet) AddPublisher(ctx context.Context, log *logging.Logger, name string, port uint16, pub Publisher, err error)
AddPublisher records a publisher started by the service, and closes it when ctx ends. err, if set, is recorded and logged instead.
func (*CXOSet) StartAggregator ¶ added in v1.3.98
func (s *CXOSet) StartAggregator(ctx context.Context, host CXOHost, log *logging.Logger, name string, port uint16, build func(n *node.Node) (Aggregator, error))
StartAggregator builds the aggregator for port with build, which gets the host's node for that port or nil (build its own). It runs until ctx ends. On a lent node the host's own Roots on that port are fed to it, since a node never receives its own feed from a peer. A failure is logged and recorded; the service carries on without that aggregator.
type ChartsPager ¶ added in v1.3.101
ChartsPager is a service with a charts page. A host shows the pages of all its services together as one status page.
type Common ¶ added in v1.3.98
type Common struct {
// PubKey and SecKey are the service's dmsg identity. A service
// embedded in a visor uses the visor's instead.
PubKey cipher.PubKey `json:"public_key,omitempty"`
SecKey cipher.SecKey `json:"secret_key,omitempty"`
// Addr is the plain-HTTP listen address.
Addr string `json:"addr,omitempty"`
// Mode selects the listeners: "http", "dmsg" or "dual"
// (see pkg/services/svcmode).
Mode string `json:"mode,omitempty"`
// DmsgPort is the dmsghttp listener port (default 80).
DmsgPort uint16 `json:"dmsg_port,omitempty"`
// Redis is the redis URL of the service's store. With Testing and no
// URL, the store is in memory.
Redis string `json:"redis,omitempty"`
// RedisPoolSize is the redis connection pool size (default 10).
RedisPoolSize int `json:"redis_pool_size,omitempty"`
// EntryTimeout is how long an entry lives without a refresh.
EntryTimeout Duration `json:"entry_timeout,omitempty"`
// LogLevel is the minimum log level; Tag names the service's logger.
LogLevel string `json:"log_level,omitempty"`
Tag string `json:"tag,omitempty"`
// LogHookLevel is the most verbose level kept for /debug/log, info when empty.
LogHookLevel string `json:"log_hook_level,omitempty"`
// MetricsAddr exposes Prometheus metrics; empty disables it.
MetricsAddr string `json:"metrics_addr,omitempty"`
// PprofMode is cpu, mem, mutex, block, trace or http (see StartPprof);
// PprofAddr is the address the http mode serves on. An address with
// no mode means http; neither disables profiling.
PprofMode string `json:"pprof_mode,omitempty"`
PprofAddr string `json:"pprof_addr,omitempty"`
// Testing runs the service for a test network: the store is in memory
// unless Redis is set, and checks that only make sense on the public
// network are relaxed. Requests are authenticated as always.
Testing bool `json:"testing,omitempty"`
// SurveyWhitelist are the keys allowed to read the service's debug and
// survey endpoints. Empty means the deployment's list (see SurveyKeys).
SurveyWhitelist []cipher.PubKey `json:"survey_whitelist,omitempty"`
}
Common is the configuration every discovery-type service shares (transport-discovery, address-resolver, route-finder, service-discovery, dmsg-discovery). Each service's Config embeds it, so the same keys mean the same thing in every block.
func (*Common) Identity ¶
Identity returns the configured key pair, deriving the public key when only the secret key is set, and the dmsghttp port and address.
func (*Common) Listen ¶
func (c *Common) Listen(ctx context.Context, id Identity, l Listener, log *logging.Logger) (*svcmode.Handle, error)
Listen starts the HTTP and dmsghttp listeners selected by Common.Mode.
func (*Common) NonceStoreConfig ¶ added in v1.3.98
func (c *Common) NonceStoreConfig(plainHTTP bool) storeconfig.Config
NonceStoreConfig is the auth nonce store: see NonceStoreType.
func (*Common) RedisURL ¶ added in v1.3.98
RedisURL is Redis with its scheme, or the local default. A unix:// URL (a socket path, for a redis on the same host) is kept as it is.
func (*Common) StartPprof ¶ added in v1.3.98
StartPprof starts profiling as PprofMode and PprofAddr select, the same way in every service and in the visor. The returned func finalizes a file profile (cpu, mem, ...) on shutdown.
func (*Common) StoreConfig ¶ added in v1.3.98
func (c *Common) StoreConfig() storeconfig.Config
StoreConfig is the service's store: see StoreType, RedisURL and PoolSize.
func (*Common) StoreType ¶ added in v1.3.98
func (c *Common) StoreType() storeconfig.Type
StoreType is the store the service uses: memory when Testing without a redis URL, redis otherwise.
func (*Common) SurveyKeys ¶ added in v1.3.98
SurveyKeys is SurveyWhitelist, or the deployment's whitelist.
type Duration ¶
Duration is a JSON-friendly wrapper around time.Duration.
func (Duration) MarshalJSON ¶
MarshalJSON renders as a Go-style duration string ("2m").
func (Duration) Std ¶
Std returns the wrapped value as the standard time.Duration so callers don't have to repeat the type assertion.
func (*Duration) UnmarshalJSON ¶
UnmarshalJSON accepts either a duration string ("2m", "5s") or a raw number (nanoseconds, matching time.Duration's MarshalJSON default).
type Embeddable ¶ added in v1.3.98
Embeddable is a Service that can also run inside a host process. Embed builds the service, starts its background work, and returns the HTTP handler for the host to mount. It returns as soon as the service is up; the service stops when ctx is canceled.
type Factory ¶
Factory builds a Service from a raw block in services.json. The block is the full JSON object the operator wrote (including the "type" field, which factories typically ignore — the registry has already used it to dispatch).
type File ¶
type File struct {
Services []Block `json:"services"`
}
File is the on-disk shape of services.json.
{
"services": [
{ "type": "dmsg-discovery", ... },
{ "type": "dmsg-server", ... }
]
}
Each Block carries its full original JSON so the per-service factory can decode into its own typed config struct without losing fields the framework doesn't know about.
type FlagDefaults ¶ added in v1.3.98
type FlagDefaults struct {
// Gen is the `skywire cli config gen` flag that writes this service's
// config, e.g. "tpd".
Gen string
Addr string
Tag string
EntryTimeout time.Duration
}
FlagDefaults are a service's defaults for the shared flags.
type Flags ¶ added in v1.3.98
Flags are the command-line flags every deployment service shares. They carry the same names, shorthands and meaning in every service, and each service binds them with its own defaults and adds only what is specific to it. A --config file overlays them key by key (MergeCommon).
type Host ¶ added in v1.3.98
type Host struct {
// DmsgClient is the host's dmsg client. Nil means the service runs
// its HTTP surface only and starts none of its CXO publishers or
// aggregators (tests, or a host without dmsg).
DmsgClient *dmsg.Client
// PK and SK are the host's identity. Services that bind a CXO node
// identity use SK; PK names the host on /health.
PK cipher.PubKey
SK cipher.SecKey
// DmsgAddr is "<pk>:<port>", the dmsg address the service reports on
// /health as its own.
DmsgAddr string
// Log is the host-supplied logger for the service.
Log *logging.Logger
// CXO lends the host's CXO nodes to the service's aggregators. Nil
// when the host has none: the service then builds its own nodes.
CXO CXOHost
}
Host is what an embedding process provides to a service.
type Identity ¶
type Identity struct {
PK cipher.PubKey
SK cipher.SecKey
DmsgPort uint16
// DmsgAddr is "<pk>:<port>", empty without a key.
DmsgAddr string
}
Identity is the dmsg identity a service listens with.
type Listener ¶
type Listener struct {
// Name prefixes errors, e.g. "address-resolver".
Name string
// DefaultAddr is the plain HTTP address when Common.Addr is empty.
DefaultAddr string
Handler http.Handler
Dmsg cmdutil.DmsgConfig
Stats *charts.ServiceStats
// OnDmsgServersUpdated receives the dmsg servers the service is on.
OnDmsgServersUpdated func([]string)
}
Listener describes the listeners Listen starts for one service.
type PublisherState ¶ added in v1.3.98
type PublisherState struct {
Name string `json:"name"`
Port uint16 `json:"port"`
treestore.PublishState
node.PublisherStats
}
PublisherState describes one CXO feed the service publishes.
type Service ¶
Service is what each per-service package returns from its Factory. Run blocks until ctx is canceled or a fatal error occurs. The registry shuts services down by canceling the shared ctx — there's no separate Stop method.
type State ¶ added in v1.3.98
type State struct {
// Store is the service's data store: "redis" or "memory".
Store string `json:"store"`
// NonceStore is where the auth nonces live: "redis", "memory", or
// "none" (test mode, requests are not authenticated).
NonceStore string `json:"nonce_store,omitempty"`
// Aggregators are the CXO fan-in nodes: visors publish a feed and the
// service subscribes to each (registration, telemetry).
Aggregators []AggregatorState `json:"cxo_aggregators,omitempty"`
// Publishers are the CXO feeds the service publishes to the fleet.
Publishers []PublisherState `json:"cxo_publishers,omitempty"`
}
State is what a running service reports about itself: `skywire cli visor state` lists it for every service the visor embeds. Every service fills the same fields, so one query reads the whole deployment host.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ar pkg/services/ar/ar.go c2-vis-appsvc
|
Package ar pkg/services/ar/ar.go c2-vis-appsvc |
|
Package confbs pkg/services/confbs/confbs.go c2-vis-appsvc
|
Package confbs pkg/services/confbs/confbs.go c2-vis-appsvc |
|
Package dmsgdisc pkg/services/dmsgdisc/config.go c2-vis-appsvc
|
Package dmsgdisc pkg/services/dmsgdisc/config.go c2-vis-appsvc |
|
Package dmsgsrv pkg/services/dmsgsrv/dmsgsrv.go c2-vis-appsvc
|
Package dmsgsrv pkg/services/dmsgsrv/dmsgsrv.go c2-vis-appsvc |
|
Package geoip pkg/services/geoip/geoip.go c2-vis-appsvc
|
Package geoip pkg/services/geoip/geoip.go c2-vis-appsvc |
|
Package noop pkg/services/noop/noop.go c2-vis-appsvc
|
Package noop pkg/services/noop/noop.go c2-vis-appsvc |
|
Package rf pkg/services/rf/rf.go c2-vis-appsvc
|
Package rf pkg/services/rf/rf.go c2-vis-appsvc |
|
Package sd pkg/services/sd/config.go c2-vis-appsvc
|
Package sd pkg/services/sd/config.go c2-vis-appsvc |
|
Package sn pkg/services/sn/sn.go c2-vis-appsvc
|
Package sn pkg/services/sn/sn.go c2-vis-appsvc |
|
Package stun pkg/services/stun/stun.go c2-vis-appsvc
|
Package stun pkg/services/stun/stun.go c2-vis-appsvc |
|
Package tpd pkg/services/tpd/config.go c2-vis-appsvc
|
Package tpd pkg/services/tpd/config.go c2-vis-appsvc |
|
Package tps pkg/services/tps/tps.go c2-vis-appsvc
|
Package tps pkg/services/tps/tps.go c2-vis-appsvc |
|
Package visor pkg/services/visor/visor.go c2-vis-appsvc
|
Package visor pkg/services/visor/visor.go c2-vis-appsvc |