Expose ClusterName instead of Banner/StatePath
This commit is contained in:
parent
b9df078538
commit
adc7a807df
|
@ -19,21 +19,21 @@ const KeyLen = 32
|
||||||
|
|
||||||
// Cluster represents a running cluster configuration
|
// Cluster represents a running cluster configuration
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
|
name string
|
||||||
ml *memberlist.Memberlist
|
ml *memberlist.Memberlist
|
||||||
mlConfig *memberlist.Config
|
mlConfig *memberlist.Config
|
||||||
localNode *common.Node
|
localNode *common.Node
|
||||||
LocalName string
|
LocalName string
|
||||||
statePath string
|
|
||||||
state *state
|
state *state
|
||||||
events chan memberlist.NodeEvent
|
events chan memberlist.NodeEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
// New is used to create a new Cluster instance
|
// New is used to create a new Cluster instance
|
||||||
// The returned instance is ready to be updated with the local node settings then joined
|
// The returned instance is ready to be updated with the local node settings then joined
|
||||||
func New(init bool, clusterKey []byte, bindAddr string, bindPort int, statePath string, useIPAsName bool) (*Cluster, error) {
|
func New(name string, init bool, clusterKey []byte, bindAddr string, bindPort int, useIPAsName bool) (*Cluster, error) {
|
||||||
state := &state{}
|
state := &state{}
|
||||||
if !init {
|
if !init {
|
||||||
loadState(state, statePath)
|
loadState(state, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
clusterKey, err := computeClusterKey(state, clusterKey)
|
clusterKey, err := computeClusterKey(state, clusterKey)
|
||||||
|
@ -57,14 +57,14 @@ func New(init bool, clusterKey []byte, bindAddr string, bindPort int, statePath
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster := Cluster{
|
cluster := Cluster{
|
||||||
|
name: name,
|
||||||
ml: ml,
|
ml: ml,
|
||||||
mlConfig: mlConfig,
|
mlConfig: mlConfig,
|
||||||
LocalName: ml.LocalNode().Name,
|
LocalName: ml.LocalNode().Name,
|
||||||
// The big channel buffer is a work-around for https://github.com/hashicorp/memberlist/issues/23
|
// The big channel buffer is a work-around for https://github.com/hashicorp/memberlist/issues/23
|
||||||
// More than this many simultaneous events will deadlock cluster.members()
|
// More than this many simultaneous events will deadlock cluster.members()
|
||||||
events: make(chan memberlist.NodeEvent, 100),
|
events: make(chan memberlist.NodeEvent, 100),
|
||||||
state: state,
|
state: state,
|
||||||
statePath: statePath,
|
|
||||||
}
|
}
|
||||||
return &cluster, nil
|
return &cluster, nil
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (c *Cluster) Join(addrs []string) error {
|
||||||
|
|
||||||
// Leave saves the current state before leaving, then leaves the cluster
|
// Leave saves the current state before leaving, then leaves the cluster
|
||||||
func (c *Cluster) Leave() {
|
func (c *Cluster) Leave() {
|
||||||
c.state.save(c.statePath)
|
c.state.save(c.name)
|
||||||
c.ml.Leave(10 * time.Second)
|
c.ml.Leave(10 * time.Second)
|
||||||
c.ml.Shutdown() //nolint: errcheck
|
c.ml.Shutdown() //nolint: errcheck
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ func (c *Cluster) Members() <-chan []common.Node {
|
||||||
}
|
}
|
||||||
c.state.Nodes = nodes
|
c.state.Nodes = nodes
|
||||||
changes <- nodes
|
changes <- nodes
|
||||||
c.state.save(c.statePath)
|
c.state.save(c.name)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
return changes
|
return changes
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cluster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -16,12 +17,10 @@ type state struct {
|
||||||
Nodes []common.Node
|
Nodes []common.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultStatePath = "/var/lib/wesher/state.json"
|
var defaultStatePath = "/var/lib/wesher/%s.json"
|
||||||
|
|
||||||
func (s *state) save(statePath string) error {
|
func (s *state) save(clusterName string) error {
|
||||||
if statePath == "" {
|
statePath := fmt.Sprintf(defaultStatePath, clusterName)
|
||||||
statePath = defaultStatePath
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(path.Dir(statePath), 0700); err != nil {
|
if err := os.MkdirAll(path.Dir(statePath), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -34,10 +33,8 @@ func (s *state) save(statePath string) error {
|
||||||
return ioutil.WriteFile(statePath, stateOut, 0600)
|
return ioutil.WriteFile(statePath, stateOut, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadState(cs *state, statePath string) {
|
func loadState(cs *state, clusterName string) {
|
||||||
if statePath == "" {
|
statePath := fmt.Sprintf(defaultStatePath, clusterName)
|
||||||
statePath = defaultStatePath
|
|
||||||
}
|
|
||||||
content, err := ioutil.ReadFile(statePath)
|
content, err := ioutil.ReadFile(statePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_state_save_soad(t *testing.T) {
|
func Test_state_save_soad(t *testing.T) {
|
||||||
statePath := "/tmp/wesher.json"
|
defaultStatePath = "/tmp/%s.json"
|
||||||
key := "abcdefghijklmnopqrstuvwxyzABCDEF"
|
key := "abcdefghijklmnopqrstuvwxyzABCDEF"
|
||||||
node := common.Node{
|
node := common.Node{
|
||||||
Name: "node",
|
Name: "node",
|
||||||
|
@ -23,11 +23,11 @@ func Test_state_save_soad(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cluster.state.save(statePath); err != nil {
|
if err := cluster.state.save("test"); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
loaded := &state{}
|
loaded := &state{}
|
||||||
loadState(loaded, statePath)
|
loadState(loaded, "test")
|
||||||
|
|
||||||
if !reflect.DeepEqual(cluster.state, loaded) {
|
if !reflect.DeepEqual(cluster.state, loaded) {
|
||||||
t.Errorf("cluster state save then reload mistmatch: %s / %s", cluster.state, loaded)
|
t.Errorf("cluster state save then reload mistmatch: %s / %s", cluster.state, loaded)
|
||||||
|
|
|
@ -14,8 +14,7 @@ type config struct {
|
||||||
ClusterKey []byte `id:"cluster-key" desc:"shared key for cluster membership; must be 32 bytes base64 encoded; will be generated if not provided"`
|
ClusterKey []byte `id:"cluster-key" desc:"shared key for cluster membership; must be 32 bytes base64 encoded; will be generated if not provided"`
|
||||||
Join []string `desc:"comma separated list of hostnames or IP addresses to existing cluster members; if not provided, will attempt resuming any known state or otherwise wait for further members."`
|
Join []string `desc:"comma separated list of hostnames or IP addresses to existing cluster members; if not provided, will attempt resuming any known state or otherwise wait for further members."`
|
||||||
Init bool `desc:"whether to explicitly (re)initialize the cluster; any known state from previous runs will be forgotten"`
|
Init bool `desc:"whether to explicitly (re)initialize the cluster; any known state from previous runs will be forgotten"`
|
||||||
Banner string `id:"banner" desc:"a string appended to /etc/hosts banner to discriminate between multiple running clusters"`
|
ClusterName string `id:"cluster-name" desc:"identifier for the wesher cluster; can be used to peer with multiple clusters" default:"default"`
|
||||||
StatePath string `id:"state-path" desc:"path where the cluster state is stored; optional, depends on cluster name if not set"`
|
|
||||||
BindAddr string `id:"bind-addr" desc:"IP address to bind to for cluster membership traffic (cannot be used with --bind-iface)"`
|
BindAddr string `id:"bind-addr" desc:"IP address to bind to for cluster membership traffic (cannot be used with --bind-iface)"`
|
||||||
BindIface string `id:"bind-iface" desc:"Interface to bind to for cluster membership traffic (cannot be used with --bind-addr)"`
|
BindIface string `id:"bind-iface" desc:"Interface to bind to for cluster membership traffic (cannot be used with --bind-addr)"`
|
||||||
ClusterPort int `id:"cluster-port" desc:"port used for membership gossip traffic (both TCP and UDP); must be the same across cluster" default:"7946"`
|
ClusterPort int `id:"cluster-port" desc:"port used for membership gossip traffic (both TCP and UDP); must be the same across cluster" default:"7946"`
|
||||||
|
|
4
main.go
4
main.go
|
@ -35,7 +35,7 @@ func main() {
|
||||||
logrus.SetLevel(logLevel)
|
logrus.SetLevel(logLevel)
|
||||||
|
|
||||||
// Create the wireguard and cluster configuration
|
// Create the wireguard and cluster configuration
|
||||||
cluster, err := cluster.New(config.Init, config.ClusterKey, config.BindAddr, config.ClusterPort, config.StatePath, config.UseIPAsName)
|
cluster, err := cluster.New(config.ClusterName, config.Init, config.ClusterKey, config.BindAddr, config.ClusterPort, config.UseIPAsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Fatal("could not create cluster")
|
logrus.WithError(err).Fatal("could not create cluster")
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func main() {
|
||||||
|
|
||||||
// Prepare the /etc/hosts writer
|
// Prepare the /etc/hosts writer
|
||||||
hostsFile := &etchosts.EtcHosts{
|
hostsFile := &etchosts.EtcHosts{
|
||||||
Banner: "# ! managed automatically by wesher " + config.Banner,
|
Banner: "# ! managed automatically by wesher " + config.ClusterName,
|
||||||
Logger: logrus.StandardLogger(),
|
Logger: logrus.StandardLogger(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ test_cluster_simultaneous_start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
test_multiple_clusters_restart() {
|
test_multiple_clusters_restart() {
|
||||||
cluster1='--cluster-port 7946 --wireguard-port 51820 --banner cluster1 --state-path /var/lib/wesher/cluster1.json --interface wgoverlay --overlay-net 10.10.0.0/16'
|
cluster1='--cluster-port 7946 --wireguard-port 51820 --cluster-name cluster1 --interface wgoverlay --overlay-net 10.10.0.0/16'
|
||||||
cluster2='--cluster-port 7947 --wireguard-port 51821 --banner cluster2 --state-path /var/lib/wesher/cluster2.json --interface wgoverlay2 --overlay-net 10.11.0.0/16'
|
cluster2='--cluster-port 7947 --wireguard-port 51821 --cluster-name cluster2 --interface wgoverlay2 --overlay-net 10.11.0.0/16'
|
||||||
setup_wireguard='wireguard-go wgoverlay2 2>/dev/null >/dev/null'
|
setup_wireguard='wireguard-go wgoverlay2 2>/dev/null >/dev/null'
|
||||||
join_cluster2="nohup /app/wesher --cluster-key 'ILICZ3yBMCGAWNIq5Pn0bewBVimW3Q2yRVJ/Be+b1Uc=' --join test2-orig $cluster2 2>/dev/null &"
|
join_cluster2="nohup /app/wesher --cluster-key 'ILICZ3yBMCGAWNIq5Pn0bewBVimW3Q2yRVJ/Be+b1Uc=' --join test2-orig $cluster2 2>/dev/null &"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue