"discovery: mDNS/DNS-SD peer discovery; dynamic upstream management"

Allows ncro instances to discover each other dynamically without static
configuration and enables a peer-to-peer style (hello funny cube) mesh
where nodes share cached builds locally instead of all hitting upstream
caches.

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I7d723876c6816cb6aaaf3fe14cb24a426a6a6964
This commit is contained in:
raf 2026-03-27 20:03:37 +03:00
commit 5fc3b2883b
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
6 changed files with 336 additions and 3 deletions

View file

@ -71,6 +71,15 @@ type MeshConfig struct {
GossipInterval Duration `yaml:"gossip_interval"`
}
// Controls mDNS/DNS-SD based dynamic upstream discovery.
type DiscoveryConfig struct {
Enabled bool `yaml:"enabled"`
ServiceName string `yaml:"service_name"`
Domain string `yaml:"domain"`
DiscoveryTime Duration `yaml:"discovery_time"`
Priority int `yaml:"priority"`
}
type LoggingConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
@ -81,6 +90,7 @@ type Config struct {
Upstreams []UpstreamConfig `yaml:"upstreams"`
Cache CacheConfig `yaml:"cache"`
Mesh MeshConfig `yaml:"mesh"`
Discovery DiscoveryConfig `yaml:"discovery"`
Logging LoggingConfig `yaml:"logging"`
}
@ -106,6 +116,12 @@ func defaults() Config {
BindAddr: "0.0.0.0:7946",
GossipInterval: Duration{30 * time.Second},
},
Discovery: DiscoveryConfig{
ServiceName: "_nix-serve._tcp",
Domain: "local",
DiscoveryTime: Duration{5 * time.Second},
Priority: 20,
},
Logging: LoggingConfig{
Level: "info",
Format: "json",
@ -161,6 +177,17 @@ func (c *Config) Validate() error {
}
}
}
if c.Discovery.Enabled {
if c.Discovery.ServiceName == "" {
return fmt.Errorf("discovery.service_name is required when discovery is enabled")
}
if c.Discovery.Domain == "" {
return fmt.Errorf("discovery.domain is required when discovery is enabled")
}
if c.Discovery.DiscoveryTime.Duration <= 0 {
return fmt.Errorf("discovery.discovery_time must be positive")
}
}
return nil
}