mirror of https://github.com/docker/docs.git
Merge pull request #851 from aluzzardi/discovery-prefix
discovery: KV Path is now an optional prefix.
This commit is contained in:
commit
62e46100cb
|
|
@ -11,13 +11,17 @@ import (
|
|||
"github.com/docker/swarm/pkg/store"
|
||||
)
|
||||
|
||||
const (
|
||||
discoveryPath = "docker/swarm/nodes"
|
||||
)
|
||||
|
||||
// Discovery is exported
|
||||
type Discovery struct {
|
||||
backend store.Backend
|
||||
store store.Store
|
||||
heartbeat time.Duration
|
||||
ttl time.Duration
|
||||
prefix string
|
||||
path string
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -34,23 +38,20 @@ func Init() {
|
|||
// Initialize is exported
|
||||
func (s *Discovery) Initialize(uris string, heartbeat time.Duration, ttl time.Duration) error {
|
||||
var (
|
||||
parts = strings.SplitN(uris, "/", 2)
|
||||
ips = strings.Split(parts[0], ",")
|
||||
addrs []string
|
||||
err error
|
||||
parts = strings.SplitN(uris, "/", 2)
|
||||
addrs = strings.Split(parts[0], ",")
|
||||
prefix = ""
|
||||
err error
|
||||
)
|
||||
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid format %q, missing <path>", uris)
|
||||
}
|
||||
|
||||
for _, ip := range ips {
|
||||
addrs = append(addrs, ip)
|
||||
// A custom prefix to the path can be optionally used.
|
||||
if len(parts) == 2 {
|
||||
prefix = parts[1]
|
||||
}
|
||||
|
||||
s.heartbeat = heartbeat
|
||||
s.ttl = ttl
|
||||
s.prefix = parts[1]
|
||||
s.path = path.Join(prefix, discoveryPath)
|
||||
|
||||
// Creates a new store, will ignore options given
|
||||
// if not supported by the chosen store
|
||||
|
|
@ -108,7 +109,7 @@ func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-c
|
|||
// Will only stop if we receive a stopCh request.
|
||||
for {
|
||||
// Set up a watch.
|
||||
watchCh, err := s.store.WatchTree(s.prefix, stopCh)
|
||||
watchCh, err := s.store.WatchTree(s.path, stopCh)
|
||||
if err != nil {
|
||||
errCh <- err
|
||||
} else {
|
||||
|
|
@ -129,7 +130,7 @@ func (s *Discovery) Watch(stopCh <-chan struct{}) (<-chan discovery.Entries, <-c
|
|||
// Register is exported
|
||||
func (s *Discovery) Register(addr string) error {
|
||||
opts := &store.WriteOptions{Ephemeral: true, Heartbeat: s.heartbeat}
|
||||
return s.store.Put(path.Join(s.prefix, addr), []byte(addr), opts)
|
||||
return s.store.Put(path.Join(s.path, addr), []byte(addr), opts)
|
||||
}
|
||||
|
||||
// Store returns the underlying store used by KV discovery.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package kv
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -13,14 +14,18 @@ import (
|
|||
|
||||
func TestInitialize(t *testing.T) {
|
||||
d := &Discovery{backend: store.MOCK}
|
||||
assert.EqualError(t, d.Initialize("127.0.0.1", 0, 0), "invalid format \"127.0.0.1\", missing <path>")
|
||||
assert.NoError(t, d.Initialize("127.0.0.1", 0, 0))
|
||||
s := d.store.(*store.Mock)
|
||||
assert.Len(t, s.Endpoints, 1)
|
||||
assert.Equal(t, s.Endpoints[0], "127.0.0.1")
|
||||
assert.Equal(t, d.path, discoveryPath)
|
||||
|
||||
d = &Discovery{backend: store.MOCK}
|
||||
assert.NoError(t, d.Initialize("127.0.0.1:1234/path", 0, 0))
|
||||
s := d.store.(*store.Mock)
|
||||
s = d.store.(*store.Mock)
|
||||
assert.Len(t, s.Endpoints, 1)
|
||||
assert.Equal(t, s.Endpoints[0], "127.0.0.1:1234")
|
||||
assert.Equal(t, d.prefix, "path")
|
||||
assert.Equal(t, d.path, "path/"+discoveryPath)
|
||||
|
||||
d = &Discovery{backend: store.MOCK}
|
||||
assert.NoError(t, d.Initialize("127.0.0.1:1234,127.0.0.2:1234,127.0.0.3:1234/path", 0, 0))
|
||||
|
|
@ -29,7 +34,7 @@ func TestInitialize(t *testing.T) {
|
|||
assert.Equal(t, s.Endpoints[0], "127.0.0.1:1234")
|
||||
assert.Equal(t, s.Endpoints[1], "127.0.0.2:1234")
|
||||
assert.Equal(t, s.Endpoints[2], "127.0.0.3:1234")
|
||||
assert.Equal(t, d.prefix, "path")
|
||||
assert.Equal(t, d.path, "path/"+discoveryPath)
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
|
|
@ -40,16 +45,16 @@ func TestWatch(t *testing.T) {
|
|||
mockCh := make(chan []*store.KVPair)
|
||||
|
||||
// The first watch will fail.
|
||||
s.On("WatchTree", "path", mock.Anything).Return(mockCh, errors.New("test error")).Once()
|
||||
s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, errors.New("test error")).Once()
|
||||
// The second one will succeed.
|
||||
s.On("WatchTree", "path", mock.Anything).Return(mockCh, nil).Once()
|
||||
s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, nil).Once()
|
||||
expected := discovery.Entries{
|
||||
&discovery.Entry{Host: "1.1.1.1", Port: "1111"},
|
||||
&discovery.Entry{Host: "2.2.2.2", Port: "2222"},
|
||||
}
|
||||
kvs := []*store.KVPair{
|
||||
{Key: "path/1.1.1.1", Value: []byte("1.1.1.1:1111")},
|
||||
{Key: "path/1.1.1.1", Value: []byte("2.2.2.2:2222")},
|
||||
{Key: path.Join("path", discoveryPath, "1.1.1.1"), Value: []byte("1.1.1.1:1111")},
|
||||
{Key: path.Join("path", discoveryPath, "2.2.2.2"), Value: []byte("2.2.2.2:2222")},
|
||||
}
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
|
|
@ -69,13 +74,13 @@ func TestWatch(t *testing.T) {
|
|||
|
||||
// Add a new entry.
|
||||
expected = append(expected, &discovery.Entry{Host: "3.3.3.3", Port: "3333"})
|
||||
kvs = append(kvs, &store.KVPair{Key: "path/3.3.3.3", Value: []byte("3.3.3.3:3333")})
|
||||
kvs = append(kvs, &store.KVPair{Key: path.Join("path", discoveryPath, "3.3.3.3"), Value: []byte("3.3.3.3:3333")})
|
||||
mockCh <- kvs
|
||||
assert.Equal(t, <-ch, expected)
|
||||
|
||||
// Make sure that if an error occurs it retries.
|
||||
// This third call to WatchTree will be checked later by AssertExpectations.
|
||||
s.On("WatchTree", "path", mock.Anything).Return(mockCh, nil)
|
||||
s.On("WatchTree", "path/"+discoveryPath, mock.Anything).Return(mockCh, nil)
|
||||
close(mockCh)
|
||||
// Give it enough time to call WatchTree.
|
||||
time.Sleep(3)
|
||||
|
|
|
|||
|
|
@ -95,13 +95,13 @@ On each of your nodes, start the Swarm agent. The node IP address
|
|||
doesn't have to be public as long as the swarm manager can access it.
|
||||
|
||||
```bash
|
||||
swarm join --addr=<node_ip:2375> etcd://<etcd_ip>/<path>
|
||||
swarm join --addr=<node_ip:2375> etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>
|
||||
```
|
||||
|
||||
Start the manager on any machine or your laptop.
|
||||
|
||||
```bash
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> etcd://<etcd_ip>/<path>
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>
|
||||
```
|
||||
|
||||
And then use the regular Docker commands.
|
||||
|
|
@ -117,7 +117,7 @@ docker -H tcp://<swarm_ip:swarm_port> logs ...
|
|||
You can list the nodes in your cluster.
|
||||
|
||||
```bash
|
||||
swarm list etcd://<etcd_ip>/<path>
|
||||
swarm list etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>
|
||||
<node_ip:2375>
|
||||
```
|
||||
|
||||
|
|
@ -127,13 +127,13 @@ On each of your nodes, start the Swarm agent. The node IP address
|
|||
doesn't need to be public as long as the Swarm manager can access it.
|
||||
|
||||
```bash
|
||||
swarm join --addr=<node_ip:2375> consul://<consul_addr>/<path>
|
||||
swarm join --addr=<node_ip:2375> consul://<consul_addr>/<optional path prefix>
|
||||
```
|
||||
|
||||
Start the manager on any machine or your laptop.
|
||||
|
||||
```bash
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> consul://<consul_addr>/<path>
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> consul://<consul_addr>/<optional path prefix>
|
||||
```
|
||||
|
||||
And then use the regular Docker commands.
|
||||
|
|
@ -149,7 +149,7 @@ docker -H tcp://<swarm_ip:swarm_port> logs ...
|
|||
You can list the nodes in your cluster.
|
||||
|
||||
```bash
|
||||
swarm list consul://<consul_addr>/<path>
|
||||
swarm list consul://<consul_addr>/<optional path prefix>
|
||||
<node_ip:2375>
|
||||
```
|
||||
|
||||
|
|
@ -159,13 +159,13 @@ On each of your nodes, start the Swarm agent. The node IP doesn't have
|
|||
to be public as long as the swarm manager can access it.
|
||||
|
||||
```bash
|
||||
swarm join --addr=<node_ip:2375> zk://<zookeeper_addr1>,<zookeeper_addr2>/<path>
|
||||
swarm join --addr=<node_ip:2375> zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix>
|
||||
```
|
||||
|
||||
Start the manager on any machine or your laptop.
|
||||
|
||||
```bash
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> zk://<zookeeper_addr1>,<zookeeper_addr2>/<path>
|
||||
swarm manage -H tcp://<swarm_ip:swarm_port> zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix>
|
||||
```
|
||||
|
||||
You can then use the regular Docker commands.
|
||||
|
|
@ -181,7 +181,7 @@ docker -H tcp://<swarm_ip:swarm_port> logs ...
|
|||
You can list the nodes in the cluster.
|
||||
|
||||
```bash
|
||||
swarm list zk://<zookeeper_addr1>,<zookeeper_addr2>/<path>
|
||||
swarm list zk://<zookeeper_addr1>,<zookeeper_addr2>/<optional path prefix>
|
||||
<node_ip:2375>
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue