Help us shape the future of Go! Take the 2026 Go Developer Survey

deployment

package
v1.3.101 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package deployment github.com/skycoin/skywire/deployment/config.go

The init() that populates Prod / Test / ProdConf / TestConf lives in two build-tag-gated files: config_native.go (//go:build !js) unmarshals the embedded services-config.json via encoding/json with SKYDEPLOY override support; config_js.go (//go:build js) copies from static Go literals in data_static_js.go (generated from the same JSON by deployment/internal/gen — see that package's doc for the why-and-how). Reason for the split: encoding/json pulls reflect.unsafe_New / mapassign / etc. that TinyGo's stdlib doesn't provide, which blocked TinyGo from compiling the install-page WASM (pkg/skywireconfig/genvisor + autoconfigcmd).

Package deployment pkg/deployment/config_native.go

Native (non-WASM) init for the deployment vars. Unmarshals the embedded services-config.json (or an external file pointed at by SKYDEPLOY) into Prod / Test / ProdConf / TestConf via encoding/json. The js/wasm build starts from the static literals instead; see config_js.go and data_static_js.go.

Package deployment deploy_config.go

Build-tag-gated off the WASM path: imports encoding/json (DeployConfig.Save uses json.NewEncoder) and references EnvServices (only available under !js, since EnvServices's json.RawMessage field needs encoding/json). The install-page WASM doesn't need DeployConfig — it only consumes the embedded Prod / Test bundles.

DeployConfig defines the unified JSON configuration format for a skywire deployment. It extends the existing services-config.json (which defines service URLs and PKs visible to visors) with per-service operational config (ports, redis, TTLs, keyfiles, pprof).

Each service reads its own section from the file. Secret keys are stored in separate keyfiles (referenced by path) rather than inline, so the config can be shared without exposing secrets.

Usage:

skywire svc tpd --deploy-config /etc/skywire/deploy.json --env prod

The --deploy-config flag is optional — services still accept all existing flags. When both are specified, flags override config file values.

Generate a template with:

skywire svc deploy-template [--env prod|test]

Package deployment keyfile.go

Package deployment keyring.go

Build-tag-gated off the WASM path: imports encoding/json for Marshal/Unmarshal of the keyring file. Keyring tooling is deploy-operator scope (running locally to mint a new deployment), not visor-runtime — and definitely not WASM, where there's no filesystem to hold a keyring file anyway.

Keyring is a single JSON file that holds all public/secret key pairs for a skywire deployment — services, dmsg servers, route setup nodes, transport setup nodes, survey whitelist, network monitors, and the reward system.

The file is NOT committed to the repo. It lives on the operator's machine and is used to:

  • Derive individual keyfiles for each service
  • Populate compose.yaml env vars
  • Generate the public-key-only deployment config (services-config.json)

Generate a template:

skywire svc keyring template > keyring.json

Generate all keyfiles from the keyring:

skywire svc keyring export --dir ./keys

Print only public keys (safe to share):

skywire svc keyring pks

Package deployment deployment/load.go

Index

Constants

View Source
const ServicesCXOPath = "services/current"

ServicesCXOPath is the leaf of the conf service's CXO feed (on skyenv.DmsgConfCXOPort) that holds the deployment's current Services, gzipped JSON. The conf service publishes it; visors subscribe to it.

Variables

View Source
var ServicesJSON []byte

ServicesJSON is the deployment configuration. By default this is the embedded services-config.json. If the SKYDEPLOY environment variable is set to a file path, that file is loaded instead at init time.

Functions

func DmsgServerEntriesToDisc

func DmsgServerEntriesToDisc(in []DmsgServerEntry) []*disc.Entry

DmsgServerEntriesToDisc converts a list of DmsgServerEntry to []*disc.Entry suitable for direct.NewClient / direct.GetAllEntries. Entries whose Static field is not a valid public key are skipped silently — the deployment file is the source of truth and a single malformed entry should not abort the whole preload.

func EmbeddedServersForDiscoveryDmsg

func EmbeddedServersForDiscoveryDmsg(discoveryDmsgURL string) []*disc.Entry

EmbeddedServersForDiscoveryDmsg returns the embedded dmsg-server transit entries belonging to the embedded deployment whose dmsg-discovery matches discoveryDmsgURL (compared by public key), or nil when nothing matches or the URL is empty/malformed.

This lets a dmsg-server omit its `servers` list yet still bootstrap, by borrowing the binary's embedded server set — but ONLY for a recognized discovery, so transit servers stay coupled to the discovery they belong to. An unknown discovery yields nil (the server keeps an empty list), never a mismatched set from a different deployment.

func EmbeddedServersForDiscoveryPK

func EmbeddedServersForDiscoveryPK(want cipher.PubKey) []*disc.Entry

EmbeddedServersForDiscoveryPK is EmbeddedServersForDiscoveryDmsg keyed by an already-parsed discovery public key, for callers that resolved the PK before reaching here. The zero key matches nothing.

The coupling this enforces is the whole point: embedded servers are only ever handed out for the discovery they were published alongside. A caller holding a private or test deployment's discovery gets nil rather than the production fleet, so no deployment silently dials servers belonging to another one.

func LoadFile added in v1.3.101

func LoadFile(path string) error

LoadFile replaces the deployment with the services-config at path, as SKYDEPLOY does at start. A browser visor has no environment at start, so autoconfig calls it there once it has read SKYDEPLOY from skywire.conf.

func ParseDuration

func ParseDuration(s string) time.Duration

ParseDuration is a helper that parses a duration string, returning 0 on empty.

func PrintTemplate

func PrintTemplate(env string) error

PrintTemplate prints the default DeployConfig as formatted JSON.

func ReadKeyfile

func ReadKeyfile(path string) (cipher.SecKey, error)

ReadKeyfile reads a secret key from a file. The file should contain just the hex-encoded secret key, optionally with whitespace/newlines.

func ResolveSecKey

func ResolveSecKey(keyfile string, skHex string) (cipher.SecKey, error)

ResolveSecKey returns a secret key from either a keyfile path or a direct hex value. Keyfile takes precedence if both are provided. Returns a zero key if neither is provided.

func SaveKeyring

func SaveKeyring(path string, kr *Keyring) error

SaveKeyring writes a keyring to a JSON file with restricted permissions.

Types

type Conf

type Conf struct {
	Conf string `json:"conf,omitempty"`
}

Conf is the configuration URL for the deployment which may be fetched on `skywire cli config gen`

var ProdConf Conf

ProdConf is the service configuration address / URL for the skywire production deployment

var TestConf Conf

TestConf is the service configuration address / URL for the skywire test deployment

type DeployConfig

type DeployConfig struct {
	Prod *DeployEnvConfig `json:"prod,omitempty"`
	Test *DeployEnvConfig `json:"test,omitempty"`
}

DeployConfig is the top-level config with prod/test environments.

func DefaultDeployConfig

func DefaultDeployConfig() *DeployConfig

DefaultDeployConfig returns a template DeployConfig with sensible defaults that can be customized for a specific deployment.

func LoadDeployConfig

func LoadDeployConfig(path string) (*DeployConfig, error)

LoadDeployConfig reads a DeployConfig from a JSON file.

type DeployEnvConfig

type DeployEnvConfig struct {
	// Embed the existing services-config fields (URLs, PKs, servers).
	EnvServices `json:",inline"`

	// Per-service operational config.
	Services struct {
		DmsgDiscovery      *ServiceConfig `json:"dmsg_discovery,omitempty"`
		TransportDiscovery *ServiceConfig `json:"transport_discovery,omitempty"`
		AddressResolver    *ServiceConfig `json:"address_resolver,omitempty"`
		RouteFinder        *ServiceConfig `json:"route_finder,omitempty"`
		ServiceDiscovery   *ServiceConfig `json:"service_discovery,omitempty"`
		SetupNode          *ServiceConfig `json:"setup_node,omitempty"`
		NetworkMonitor     *ServiceConfig `json:"network_monitor,omitempty"`
		ConfService        *ServiceConfig `json:"conf_service,omitempty"`
		GeoIP              *ServiceConfig `json:"geoip,omitempty"`
		Stun               *ServiceConfig `json:"stun,omitempty"`
		TransportSetup     *ServiceConfig `json:"transport_setup,omitempty"`
	} `json:"services,omitempty"`

	// DmsgServers lists dmsg server instances for this environment.
	DmsgServerInstances []DmsgServerConfig `json:"dmsg_server_instances,omitempty"`

	// Infrastructure.
	Redis struct {
		URL      string `json:"url,omitempty"`
		Password string `json:"password,omitempty"`
	} `json:"redis,omitempty"`
}

DeployEnvConfig holds the full deployment config for one environment.

type DmsgServerConfig

type DmsgServerConfig struct {
	// Name is the container/instance name (e.g., "dmsg-server-1").
	Name string `json:"name"`

	// ConfigFile is the path to the dmsg server's JSON config.
	ConfigFile string `json:"config_file"`

	// PublicPort is the host port mapped to the server's listen port.
	PublicPort int `json:"public_port"`

	// PprofAddr is the pprof listen address.
	PprofAddr string `json:"pprof,omitempty"`
}

DmsgServerConfig holds config for a single dmsg server instance.

type DmsgServerEntry

type DmsgServerEntry struct {
	Static string `json:"static"`
	Server struct {
		Address string `json:"address"`
		// AddressWS is the optional full ws:// or wss:// WebSocket URL (including
		// the /dmsg path, e.g. "wss://dmsg1.example.net/dmsg") a browser client
		// seeds from. It is SEPARATE from Address (IP:port, TCP): native visors
		// dial Address and never look at AddressWS, so advertising a wss:// domain
		// here adds no DNS/TLS dependency for them. Required for a wasm-visor
		// served over HTTPS, whose browser blocks plain ws:// (mixed content); a
		// wss domain's CA cert is stable, so it lives safely in the embedded config.
		AddressWS string `json:"address_ws,omitempty"`
	} `json:"server"`
}

DmsgServerEntry represents a DMSG server with its public key and address. This is a simplified representation that avoids importing dmsg/disc. Use ToDiscEntries() to convert to []*disc.Entry when needed.

type EnvServices

type EnvServices struct {
	Test json.RawMessage `json:"test"`
	Prod json.RawMessage `json:"prod"`
}

EnvServices is the wrapper struct for the outer JSON — i.e. the 'prod' or 'test' deployment config. It lives in this untagged file (importing encoding/json, which compiles under TinyGo 0.41) so consumers like pkg/dmsg/dmsg's InitConfig can unmarshal the embedded config on every target, including a TinyGo dmsg client. The native init() in config_native.go and the static-literal init() in config_js.go both populate Prod/Test; this type is just the shared shape they (and dmsg) decode into.

type KeyPair

type KeyPair struct {
	PK cipher.PubKey `json:"pk"`
	SK cipher.SecKey `json:"sk"`
}

KeyPair holds a public and secret key for a deployment identity.

type Keyring

type Keyring struct {
	// Services
	DmsgDiscovery      *KeyPair `json:"dmsg_discovery,omitempty"`
	TransportDiscovery *KeyPair `json:"transport_discovery,omitempty"`
	AddressResolver    *KeyPair `json:"address_resolver,omitempty"`
	RouteFinder        *KeyPair `json:"route_finder,omitempty"`
	ServiceDiscovery   *KeyPair `json:"service_discovery,omitempty"`
	SetupNode          *KeyPair `json:"setup_node,omitempty"`
	ConfService        *KeyPair `json:"conf_service,omitempty"`
	NetworkMonitor     *KeyPair `json:"network_monitor,omitempty"`

	// DMSG servers (multiple)
	DmsgServers []NamedKeyPair `json:"dmsg_servers,omitempty"`

	// Route setup nodes (multiple — includes embedded RSN keys)
	RouteSetupNodes []NamedKeyPair `json:"route_setup_nodes,omitempty"`

	// Transport setup nodes (multiple — includes embedded TPS keys)
	TransportSetupNodes []NamedKeyPair `json:"transport_setup_nodes,omitempty"`

	// Survey whitelist
	SurveyWhitelist []NamedKeyPair `json:"survey_whitelist,omitempty"`

	// Network monitor keys (multiple — for deregistration authorization)
	NetworkMonitorKeys []NamedKeyPair `json:"network_monitor_keys,omitempty"`

	// Reward system
	RewardSystem *KeyPair `json:"reward_system,omitempty"`

	// Visor (the deployment's own visor, if any)
	Visor *KeyPair `json:"visor,omitempty"`
}

Keyring holds all key pairs for a skywire deployment.

func LoadKeyring

func LoadKeyring(path string) (*Keyring, error)

LoadKeyring reads a keyring from a JSON file.

func (*Keyring) ExportKeyfiles

func (kr *Keyring) ExportKeyfiles(dir string) error

ExportKeyfiles writes each key pair to a separate file in the given directory. The filename is the identity name (e.g., "dmsg_discovery.key").

func (*Keyring) PublicKeys

func (kr *Keyring) PublicKeys() map[string]string

PublicKeys returns a summary of all public keys (safe to share/print).

type NamedKeyPair

type NamedKeyPair struct {
	Name string        `json:"name"`
	PK   cipher.PubKey `json:"pk"`
	SK   cipher.SecKey `json:"sk"`
}

NamedKeyPair is a KeyPair with a human-readable name.

type ServiceConfig

type ServiceConfig struct {
	// Addr is the HTTP listen address (e.g., ":9094").
	Addr string `json:"addr,omitempty"`

	// Keyfile is the path to a file containing the service's secret key.
	// Preferred over inline SK for security.
	Keyfile string `json:"keyfile,omitempty"`

	// Redis is the Redis connection URL (e.g., "redis://redis:6379").
	Redis string `json:"redis,omitempty"`

	// RedisPoolSize is the Redis connection pool size.
	RedisPoolSize int `json:"redis_pool_size,omitempty"`

	// DmsgDisc is the DMSG discovery URL used by this service.
	DmsgDisc string `json:"dmsg_disc,omitempty"`

	// PprofAddr is the pprof HTTP listen address (e.g., ":6094").
	PprofAddr string `json:"pprof,omitempty"`

	// EntryTimeout is the TTL for entries managed by this service.
	EntryTimeout string `json:"entry_timeout,omitempty"`

	// WhitelistKeys are network monitor PKs authorized to deregister entries.
	WhitelistKeys []string `json:"whitelist_keys,omitempty"`

	// Mode is the listener mode: "http", "dmsg", or "dual".
	Mode string `json:"mode,omitempty"`

	// ConfigFile is a path to an additional service-specific config file
	// (e.g., dmsg-server config.json, setup-node config.json).
	ConfigFile string `json:"config_file,omitempty"`

	// GodebugEnv is the GODEBUG environment variable value.
	GodebugEnv string `json:"godebug,omitempty"`
}

ServiceConfig holds operational config for a single deployment service. Each field maps to an existing CLI flag.

type Services

type Services struct {
	// HTTP endpoints
	DmsgDiscovery      string          `json:"dmsg_discovery,omitempty"`
	TransportDiscovery string          `json:"transport_discovery,omitempty"`
	AddressResolver    string          `json:"address_resolver,omitempty"`
	RouteFinder        string          `json:"route_finder,omitempty"`
	RouteSetupNodes    []cipher.PubKey `json:"route_setup_nodes,omitempty"`
	TransportSetupPKs  []cipher.PubKey `json:"transport_setup,omitempty"`
	ServiceDiscovery   string          `json:"service_discovery,omitempty"`
	StunServers        []string        `json:"stun_servers,omitempty"`
	DNSServer          string          `json:"dns_server,omitempty"`
	GeoIP              string          `json:"geoip,omitempty"` // HTTP only (dmsg doesn't preserve client IP)
	SurveyWhitelist    []cipher.PubKey `json:"survey_whitelist,omitempty"`
	// DMSG endpoints (dmsg:// URLs for the same services)
	ConfDmsg    string            `json:"conf_dmsg,omitempty"`
	DmsgServers []DmsgServerEntry `json:"dmsg_servers,omitempty"`
	// WSSDomainSuffix is the deployment-wide DNS suffix the official dmsg servers
	// self-derive their wss:// AddressWS from — "wss://<DNSLabel(PK)>.<suffix>/dmsg"
	// — so an HTTPS-served browser wasm-visor reaches them without mixed content.
	// One string for the whole fleet (each server self-labels from its own PK), so
	// the domain lives in exactly one place (this file) instead of every dmsg
	// server's local config. A dmsg server applies it only when its own PK is a
	// known fleet server (IsKnownDmsgServer) — a third party running this binary
	// never mis-advertises this domain for a PK with no DNS record.
	WSSDomainSuffix string `json:"wss_domain_suffix,omitempty"`
	// WSSDomainAliases are earlier suffixes a known server still answers on
	// and gets certificates for, without advertising them, so browser modules
	// built with an old name keep reaching it while the fleet moves.
	WSSDomainAliases []string `json:"wss_domain_aliases,omitempty"`
	// BrowseOriginSuffix is the deployment-wide domain the "real-origin" browse
	// path (pkg/visor/meshproxy.go, the wasm SW browse origin, and the hosted
	// Caddy front) serves untrusted mesh content under — e.g. ".theskywirenetwork.net"
	// (a SEPARATE eTLD+1 from the visor app on WSSDomainSuffix, so untrusted
	// browsed content is cookie/origin-isolated from the visor identity). Lives
	// here so the domain is defined in exactly one place instead of being
	// hardcoded across the serve flags / config-gen / docs; consumers read it via
	// deployment.Prod.BrowseOriginSuffix. Empty (the local default) means the
	// browse origin uses ".mesh.localhost" (loopback, secure-context, no cert).
	BrowseOriginSuffix string `json:"browse_origin_suffix,omitempty"`
	// WasmModuleSource is the visor that serves the current js/wasm module over
	// dmsg. Visors refresh their copy from it when the desk is opened.
	WasmModuleSource       string `json:"wasm_module_source,omitempty"`
	DmsgDiscoveryDmsg      string `json:"dmsg_discovery_dmsg,omitempty"`
	TransportDiscoveryDmsg string `json:"transport_discovery_dmsg,omitempty"`
	AddressResolverDmsg    string `json:"address_resolver_dmsg,omitempty"`
	RouteFinderDmsg        string `json:"route_finder_dmsg,omitempty"`
	ServiceDiscoveryDmsg   string `json:"service_discovery_dmsg,omitempty"`
	// Reward system
	RewardSystem     string `json:"reward_system,omitempty"`
	RewardSystemDmsg string `json:"reward_system_dmsg,omitempty"`
}

Services are URLs, IP addresses, and public keys of the skywire services as deployed. HTTP fields contain plain HTTP URLs, _dmsg fields contain dmsg:// URLs for the same services.

var Prod Services

Prod is the production deployment services

var Test Services

Test is the test deployment services

func (*Services) BackfillClearnetFromDmsg

func (s *Services) BackfillClearnetFromDmsg()

BackfillClearnetFromDmsg copies each *_dmsg deployment-service URL into its historically-clearnet sibling field when that field is empty. services-config.json no longer carries plain-HTTP deployment URLs (only geoip — the one allowed clearnet deployment endpoint, since dmsg can't preserve the client IP a geoip lookup needs), so the HTTP-named fields would otherwise be empty. In a dmsg-only deployment the correct value for them IS the dmsg:// URL, so every existing consumer of the HTTP-named fields keeps working unchanged — getHTTPClient builds a dmsghttp client for the dmsg:// scheme. The single source of truth stays services-config.json; this derives, it does not hardcode. GeoIP is deliberately left untouched.

func (*Services) HasDmsgEndpoints

func (s *Services) HasDmsgEndpoints() bool

HasDmsgEndpoints returns true if the deployment has DMSG service endpoints.

func (*Services) HasDmsgServers

func (s *Services) HasDmsgServers() bool

HasDmsgServers returns true if the deployment has DMSG server entries.

func (*Services) IsKnownDmsgServer

func (s *Services) IsKnownDmsgServer(pk cipher.PubKey) bool

IsKnownDmsgServer reports whether pk is one of the deployment's known (official) dmsg servers. Used to gate fleet-wide defaults — e.g. the WSSDomainSuffix — to servers this deployment actually runs DNS/TLS for, so a third party running the same binary doesn't self-advertise the deployment's wss domain for a PK that has no DNS record.

func (*Services) ToDiscEntries

func (s *Services) ToDiscEntries() []*disc.Entry

ToDiscEntries is the method form of DmsgServerEntriesToDisc, scoped to the receiver's DmsgServers list.

func (*Services) WSSAliasHosts added in v1.3.101

func (s *Services) WSSAliasHosts(label string) []string

WSSAliasHosts are the alias host names of a server with DNS label label.

Directories

Path Synopsis
cmd
gen command
Package main reads ../../services-config.json and emits Go-literal declarations for deployment.Prod, deployment.Test, deployment.ProdConf, and deployment.TestConf into ../../data_static_js.go.
Package main reads ../../services-config.json and emits Go-literal declarations for deployment.Prod, deployment.Test, deployment.ProdConf, and deployment.TestConf into ../../data_static_js.go.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL