package lncfg import ( "context" "fmt" "os" "github.com/lightningnetwork/lnd/cluster" ) const ( // DefaultEtcdElectionPrefix is used as election prefix if none is provided // through the config. DefaultEtcdElectionPrefix = "/leader/" ) // Cluster holds configuration for clustered LND. type Cluster struct { EnableLeaderElection bool `long:"enable-leader-election" description:"Enables leader election if set."` LeaderElector string `long:"leader-elector" choice:"etcd" description:"Leader elector to use. Valid values: \"etcd\"."` EtcdElectionPrefix string `long:"etcd-election-prefix" description:"Election key prefix when using etcd leader elector. Defaults to \"/leader/\"."` ID string `long:"id" description:"Identifier for this node inside the cluster (used in leader election). Defaults to the hostname."` } // DefaultCluster creates and returns a new default DB config. func DefaultCluster() *Cluster { hostname, _ := os.Hostname() return &Cluster{ LeaderElector: cluster.EtcdLeaderElector, EtcdElectionPrefix: DefaultEtcdElectionPrefix, ID: hostname, } } // MakeLeaderElector is a helper method to construct the concrete leader elector // based on the current configuration. func (c *Cluster) MakeLeaderElector(electionCtx context.Context, db *DB) ( cluster.LeaderElector, error) { if c.LeaderElector == cluster.EtcdLeaderElector { return cluster.MakeLeaderElector( electionCtx, c.LeaderElector, c.ID, c.EtcdElectionPrefix, db.Etcd, ) } return nil, fmt.Errorf("unsupported leader elector") } // Validate validates the Cluster config. func (c *Cluster) Validate() error { if !c.EnableLeaderElection { return nil } switch c.LeaderElector { case cluster.EtcdLeaderElector: if c.EtcdElectionPrefix == "" { return fmt.Errorf("etcd-election-prefix must be set") } return nil default: return fmt.Errorf("unknown leader elector, valid values are: "+ "\"%v\"", cluster.EtcdLeaderElector) } } // Compile-time constraint to ensure Workers implements the Validator interface. var _ Validator = (*Cluster)(nil)